summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java152
-rw-r--r--cmds/app_process/Android.bp1
-rw-r--r--core/api/current.txt4
-rw-r--r--core/api/system-current.txt25
-rw-r--r--core/api/test-current.txt5
-rw-r--r--core/java/android/app/AppCompatTaskInfo.java5
-rw-r--r--core/java/android/app/ApplicationStartInfo.java26
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java47
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java37
-rw-r--r--core/java/android/app/WallpaperManager.java25
-rw-r--r--core/java/android/app/WindowConfiguration.java6
-rw-r--r--core/java/android/app/activity_manager.aconfig27
-rw-r--r--core/java/android/app/wallpaper.aconfig10
-rw-r--r--core/java/android/content/Intent.java7
-rw-r--r--core/java/android/content/flags/flags.aconfig12
-rw-r--r--core/java/android/content/pm/UserInfo.java8
-rw-r--r--core/java/android/content/pm/multiuser.aconfig7
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java20
-rw-r--r--core/java/android/hardware/biometrics/flags.aconfig8
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java4
-rw-r--r--core/java/android/inputmethodservice/NavigationBarController.java9
-rw-r--r--core/java/android/os/Binder.java16
-rw-r--r--core/java/android/os/IpcDataCache.java3
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionManager.java32
-rw-r--r--core/java/android/security/flags.aconfig7
-rw-r--r--core/java/android/view/InsetsController.java12
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/WindowManagerGlobal.java8
-rw-r--r--core/java/android/view/inputmethod/ImeTracker.java4
-rw-r--r--core/java/android/view/inspector/WindowInspector.java5
-rw-r--r--core/java/android/view/translation/ListenerGroup.java4
-rw-r--r--core/java/android/webkit/WebSettings.java13
-rw-r--r--core/java/android/webkit/flags.aconfig8
-rw-r--r--core/java/android/window/BackMotionEvent.java22
-rw-r--r--core/java/android/window/BackTouchTracker.java9
-rw-r--r--core/java/android/window/DesktopModeFlags.java4
-rw-r--r--core/java/android/window/ImeOnBackInvokedDispatcher.java6
-rw-r--r--core/java/android/window/flags/responsible_apis.aconfig7
-rw-r--r--core/java/com/android/internal/app/AssistUtils.java2
-rw-r--r--core/java/com/android/internal/jank/Cuj.java18
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHistory.java15
-rw-r--r--core/java/com/android/internal/util/LatencyTracker.java16
-rw-r--r--core/java/com/android/internal/widget/NotificationProgressBar.java35
-rw-r--r--core/java/com/android/internal/widget/NotificationProgressDrawable.java68
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operations.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java52
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java157
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java37
-rw-r--r--core/jni/android_util_Binder.cpp34
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/drawable/notification_progress.xml5
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_base.xml1
-rw-r--r--core/res/res/layout/notification_2025_template_collapsed_media.xml1
-rw-r--r--core/res/res/values-af/strings.xml21
-rw-r--r--core/res/res/values-am/strings.xml21
-rw-r--r--core/res/res/values-ar/strings.xml3
-rw-r--r--core/res/res/values-as/strings.xml21
-rw-r--r--core/res/res/values-az/strings.xml3
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml21
-rw-r--r--core/res/res/values-be/strings.xml21
-rw-r--r--core/res/res/values-bg/strings.xml3
-rw-r--r--core/res/res/values-bn/strings.xml21
-rw-r--r--core/res/res/values-bs/strings.xml21
-rw-r--r--core/res/res/values-ca/strings.xml21
-rw-r--r--core/res/res/values-cs/strings.xml21
-rw-r--r--core/res/res/values-da/strings.xml21
-rw-r--r--core/res/res/values-de/strings.xml21
-rw-r--r--core/res/res/values-el/strings.xml21
-rw-r--r--core/res/res/values-en-rAU/strings.xml21
-rw-r--r--core/res/res/values-en-rGB/strings.xml21
-rw-r--r--core/res/res/values-en-rIN/strings.xml21
-rw-r--r--core/res/res/values-es/strings.xml21
-rw-r--r--core/res/res/values-et/strings.xml21
-rw-r--r--core/res/res/values-eu/strings.xml3
-rw-r--r--core/res/res/values-fa/strings.xml3
-rw-r--r--core/res/res/values-fi/strings.xml21
-rw-r--r--core/res/res/values-fr-rCA/strings.xml3
-rw-r--r--core/res/res/values-fr/strings.xml21
-rw-r--r--core/res/res/values-gl/strings.xml21
-rw-r--r--core/res/res/values-gu/strings.xml21
-rw-r--r--core/res/res/values-hi/strings.xml21
-rw-r--r--core/res/res/values-hr/strings.xml21
-rw-r--r--core/res/res/values-hu/strings.xml21
-rw-r--r--core/res/res/values-hy/strings.xml3
-rw-r--r--core/res/res/values-in/strings.xml21
-rw-r--r--core/res/res/values-is/strings.xml18
-rw-r--r--core/res/res/values-it/strings.xml18
-rw-r--r--core/res/res/values-iw/strings.xml21
-rw-r--r--core/res/res/values-kk/strings.xml21
-rw-r--r--core/res/res/values-kn/strings.xml3
-rw-r--r--core/res/res/values-ko/strings.xml21
-rw-r--r--core/res/res/values-ky/strings.xml21
-rw-r--r--core/res/res/values-lo/strings.xml3
-rw-r--r--core/res/res/values-lt/strings.xml3
-rw-r--r--core/res/res/values-lv/strings.xml21
-rw-r--r--core/res/res/values-mk/strings.xml21
-rw-r--r--core/res/res/values-ml/strings.xml21
-rw-r--r--core/res/res/values-mn/strings.xml21
-rw-r--r--core/res/res/values-mr/strings.xml21
-rw-r--r--core/res/res/values-my/strings.xml3
-rw-r--r--core/res/res/values-nb/strings.xml21
-rw-r--r--core/res/res/values-ne/strings.xml18
-rw-r--r--core/res/res/values-nl/strings.xml21
-rw-r--r--core/res/res/values-or/strings.xml21
-rw-r--r--core/res/res/values-pa/strings.xml21
-rw-r--r--core/res/res/values-pl/strings.xml21
-rw-r--r--core/res/res/values-pt-rBR/strings.xml21
-rw-r--r--core/res/res/values-pt-rPT/strings.xml3
-rw-r--r--core/res/res/values-pt/strings.xml21
-rw-r--r--core/res/res/values-ro/strings.xml21
-rw-r--r--core/res/res/values-ru/strings.xml21
-rw-r--r--core/res/res/values-si/strings.xml21
-rw-r--r--core/res/res/values-sk/strings.xml21
-rw-r--r--core/res/res/values-sl/strings.xml3
-rw-r--r--core/res/res/values-sq/strings.xml3
-rw-r--r--core/res/res/values-sr/strings.xml21
-rw-r--r--core/res/res/values-sv/strings.xml21
-rw-r--r--core/res/res/values-sw/strings.xml21
-rw-r--r--core/res/res/values-ta/strings.xml21
-rw-r--r--core/res/res/values-th/strings.xml21
-rw-r--r--core/res/res/values-tl/strings.xml21
-rw-r--r--core/res/res/values-tr/strings.xml21
-rw-r--r--core/res/res/values-uk/strings.xml21
-rw-r--r--core/res/res/values-uz/strings.xml3
-rw-r--r--core/res/res/values-vi/strings.xml21
-rw-r--r--core/res/res/values-zh-rCN/strings.xml21
-rw-r--r--core/res/res/values-zh-rHK/strings.xml21
-rw-r--r--core/res/res/values-zh-rTW/strings.xml21
-rw-r--r--core/res/res/values-zu/strings.xml21
-rw-r--r--core/res/res/values/attrs.xml24
-rw-r--r--core/res/res/values/styles_material.xml3
-rw-r--r--core/tests/coretests/src/android/content/IntentTest.java44
-rw-r--r--core/tests/coretests/src/android/content/pm/UserInfoTest.java90
-rw-r--r--core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java47
-rw-r--r--core/tests/coretests/src/android/window/BackTouchTrackerTest.kt2
-rw-r--r--core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java3
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig7
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml39
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml9
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml2
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java41
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt129
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java59
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java61
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleAnimator.kt101
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt20
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt110
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt31
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java123
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java50
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt3
-rw-r--r--libs/androidfw/CursorWindow.cpp2
-rw-r--r--libs/hostgraphics/include/gui/BufferItemConsumer.h4
-rw-r--r--libs/hwui/Android.bp1
-rw-r--r--libs/hwui/WebViewFunctorManager.cpp47
-rw-r--r--libs/hwui/WebViewFunctorManager.h13
-rw-r--r--libs/hwui/aconfig/hwui_flags.aconfig7
-rw-r--r--libs/hwui/jni/Bitmap.cpp29
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp14
-rw-r--r--libs/hwui/platform/host/WebViewFunctorManager.cpp2
-rw-r--r--libs/hwui/platform/host/renderthread/RenderThread.cpp2
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp64
-rw-r--r--libs/hwui/renderthread/CanvasContext.h17
-rw-r--r--libs/hwui/renderthread/ReliableSurface.cpp24
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp20
-rw-r--r--libs/hwui/renderthread/RenderProxy.h4
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp60
-rw-r--r--libs/hwui/renderthread/RenderThread.h48
-rw-r--r--media/java/android/media/AudioDeviceVolumeManager.java238
-rw-r--r--media/java/android/media/AudioManager.java90
-rw-r--r--media/java/android/media/MediaCodecInfo.java15
-rw-r--r--media/java/android/media/MediaRecorder.java2
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml2
-rw-r--r--packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java48
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml20
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java24
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java24
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java41
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java11
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java7
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml1
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml7
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml7
-rw-r--r--packages/SystemUI/Android.bp1
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig27
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt29
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java4
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt9
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt12
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/OffsetOverscrollEffect.kt2
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt2
-rw-r--r--packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt35
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt16
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt146
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt)53
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt40
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt41
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationGroupingUtilTest.kt64
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt56
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt18
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt90
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt90
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt529
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt34
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt70
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt223
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt1444
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt525
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt89
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt2
-rw-r--r--packages/SystemUI/res-keyguard/values-bn/strings.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml8
-rw-r--r--packages/SystemUI/res/values-af/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-am/strings.xml8
-rw-r--r--packages/SystemUI/res/values-am/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml8
-rw-r--r--packages/SystemUI/res/values-as/strings.xml8
-rw-r--r--packages/SystemUI/res/values-as/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-az/strings.xml8
-rw-r--r--packages/SystemUI/res/values-az/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-be/strings.xml8
-rw-r--r--packages/SystemUI/res/values-be/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bg/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bs/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ca/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-da/strings.xml8
-rw-r--r--packages/SystemUI/res/values-da/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-de/strings.xml8
-rw-r--r--packages/SystemUI/res/values-de/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-el/strings.xml8
-rw-r--r--packages/SystemUI/res/values-el/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml8
-rw-r--r--packages/SystemUI/res/values-es/strings.xml8
-rw-r--r--packages/SystemUI/res/values-et/strings.xml8
-rw-r--r--packages/SystemUI/res/values-et/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fa/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml19
-rw-r--r--packages/SystemUI/res/values-gu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml11
-rw-r--r--packages/SystemUI/res/values-hu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hy/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-is/strings.xml8
-rw-r--r--packages/SystemUI/res/values-is/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-it/strings.xml8
-rw-r--r--packages/SystemUI/res/values-it/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ja/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ka/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ko/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ky/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lo/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lv/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ml/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ms/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-my/strings.xml8
-rw-r--r--packages/SystemUI/res/values-my/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nb/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ne/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-or/strings.xml10
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pa/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml11
-rw-r--r--packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ro/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ru/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-si/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-sl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sv/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ta/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-te/strings.xml8
-rw-r--r--packages/SystemUI/res/values-te/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-th/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ur/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uz/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-vi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values/styles.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt103
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/DismissibleHorizontalPager.kt160
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt191
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToDismiss.kt115
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToReveal.kt264
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSettingsButtonViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt68
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt85
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/model/ScreenRecordChipModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt162
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt371
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt204
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt92
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt371
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt (renamed from packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt)19
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/window/data/repository/NoopWindowRootViewBlurRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt9
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt28
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/AppIconProviderKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt38
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt4
-rw-r--r--packages/WallpaperBackup/Android.bp2
-rw-r--r--packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java124
-rw-r--r--packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java49
-rw-r--r--packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java229
-rw-r--r--packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java90
-rwxr-xr-xravenwood/scripts/ravenwood-stats-collector.sh53
-rw-r--r--ravenwood/tools/hoststubgen/Android.bp1
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt33
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt35
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt96
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt62
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt7
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt50
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt28
-rw-r--r--ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt5
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt98
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py2
-rw-r--r--ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt115
-rw-r--r--services/accessibility/accessibility.aconfig10
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java19
-rw-r--r--services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java32
-rw-r--r--services/core/java/com/android/server/adb/AdbDebuggingManager.java4
-rw-r--r--services/core/java/com/android/server/am/AppStartInfoTracker.java117
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java102
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java28
-rw-r--r--services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java17
-rw-r--r--services/core/java/com/android/server/hdmi/AudioManagerWrapper.java12
-rw-r--r--services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java25
-rw-r--r--services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java12
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java26
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java4
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java10
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java4
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java31
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperCropper.java2
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java3
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java69
-rw-r--r--services/core/java/com/android/server/wm/AbsAppSnapshotController.java18
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartInterceptor.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java19
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java13
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java8
-rw-r--r--services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java42
-rw-r--r--services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java9
-rw-r--r--services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java43
-rw-r--r--services/core/java/com/android/server/wm/SnapshotPersistQueue.java81
-rw-r--r--services/core/java/com/android/server/wm/Task.java80
-rw-r--r--services/core/java/com/android/server/wm/Transition.java1
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java5
-rw-r--r--services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java2
-rw-r--r--services/java/com/android/server/SystemServer.java31
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java61
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java29
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java18
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java35
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java13
-rw-r--r--tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java63
-rw-r--r--tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java21
-rw-r--r--tests/vcn/Android.bp4
-rw-r--r--tests/vcn/AndroidManifest.xml4
-rw-r--r--tests/vcn/AndroidTest.xml2
-rw-r--r--tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java11
-rw-r--r--tests/vcn/java/android/net/vcn/VcnConfigTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnManagerTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java11
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java9
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java10
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java8
-rw-r--r--tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java9
761 files changed, 10838 insertions, 6009 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index a9c4a1501dd8..6dd7521e4d43 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -36,7 +36,6 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.UidObserver;
-import android.app.compat.CompatChanges;
import android.app.job.JobInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
@@ -54,6 +53,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.DeviceConfig;
@@ -74,6 +74,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.server.AppSchedulingModuleThread;
import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
+import com.android.server.compat.PlatformCompat;
import com.android.server.job.ConstantsProto;
import com.android.server.job.Flags;
import com.android.server.job.JobSchedulerService;
@@ -157,6 +158,15 @@ public final class QuotaController extends StateController {
@Overridable // The change can be overridden in user build.
static final long OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS = 374323858L;
+ /**
+ * When enabled this change id overrides the default quota parameters adjustment.
+ */
+ @VisibleForTesting
+ @ChangeId
+ @Disabled // Disabled by default
+ @Overridable // The change can be overridden in user build.
+ static final long OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS = 378129159L;
+
@VisibleForTesting
static class ExecutionStats {
/**
@@ -536,6 +546,8 @@ public final class QuotaController extends StateController {
*/
private final SparseSetArray<String> mSystemInstallers = new SparseSetArray<>();
+ private final PlatformCompat mPlatformCompat;
+
/** An app has reached its quota. The message should contain a {@link UserPackage} object. */
@VisibleForTesting
static final int MSG_REACHED_TIME_QUOTA = 0;
@@ -587,6 +599,13 @@ public final class QuotaController extends StateController {
PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class);
pai.registerTempAllowlistChangeListener(new TempAllowlistTracker());
+ mPlatformCompat = (PlatformCompat)
+ ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
+ if (Flags.adjustQuotaDefaultConstants()) {
+ mPlatformCompat.registerListener(OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS,
+ (packageName) -> handleQuotaDefaultConstantsCompatChange());
+ }
+
try {
ActivityManager.getService().registerUidObserver(new QcUidObserver(),
ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -651,8 +670,9 @@ public final class QuotaController extends StateController {
final int uid = jobStatus.getSourceUid();
if ((!Flags.enforceQuotaPolicyToTopStartedJobs()
- || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
- uid)) && mTopAppCache.get(uid)) {
+ || mPlatformCompat.isChangeEnabledByUid(
+ OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, uid))
+ && mTopAppCache.get(uid)) {
if (DEBUG) {
Slog.d(TAG, jobStatus.toShortString() + " is top started job");
}
@@ -690,8 +710,8 @@ public final class QuotaController extends StateController {
}
}
if (!Flags.enforceQuotaPolicyToTopStartedJobs()
- || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
- jobStatus.getSourceUid())) {
+ || mPlatformCompat.isChangeEnabledByUid(
+ OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, jobStatus.getSourceUid())) {
mTopStartedJobs.remove(jobStatus);
}
}
@@ -805,8 +825,8 @@ public final class QuotaController extends StateController {
/** @return true if the job was started while the app was in the TOP state. */
private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) {
if (!Flags.enforceQuotaPolicyToTopStartedJobs()
- || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
- jobStatus.getSourceUid())) {
+ || mPlatformCompat.isChangeEnabledByUid(
+ OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, jobStatus.getSourceUid())) {
return mTopStartedJobs.contains(jobStatus);
}
@@ -1102,6 +1122,7 @@ public final class QuotaController extends StateController {
final int standbyBucket) {
final long baseLimitMs = mAllowedTimePerPeriodMs[standbyBucket];
if (Flags.adjustQuotaDefaultConstants()
+ && !isCompatOverridedForQuotaConstantAdjustment()
&& Flags.additionalQuotaForSystemInstaller()
&& standbyBucket == EXEMPTED_INDEX
&& mSystemInstallers.contains(userId, pkgName)) {
@@ -1473,10 +1494,21 @@ public final class QuotaController extends StateController {
}
}
+ void handleQuotaDefaultConstantsCompatChange() {
+ synchronized (mLock) {
+ final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+ mQcConstants.adjustDefaultBucketWindowSizes(isCompatEnabled);
+ mQcConstants.adjustDefaultEjLimits(isCompatEnabled);
+ mQcConstants.mShouldReevaluateConstraints = true;
+ onConstantsUpdatedLocked();
+ }
+ }
+
void processQuotaConstantsAdjustment() {
- if (Flags.adjustQuotaDefaultConstants()) {
- mQcConstants.adjustDefaultBucketWindowSizes();
- mQcConstants.adjustDefaultEjLimits();
+ if (Flags.adjustQuotaDefaultConstants()
+ && !isCompatOverridedForQuotaConstantAdjustment()) {
+ mQcConstants.adjustDefaultBucketWindowSizes(false);
+ mQcConstants.adjustDefaultEjLimits(false);
}
}
@@ -1505,6 +1537,11 @@ public final class QuotaController extends StateController {
}
}
+ private boolean isCompatOverridedForQuotaConstantAdjustment() {
+ return mPlatformCompat.isChangeEnabledByPackageName(
+ OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS, "android", UserHandle.USER_SYSTEM);
+ }
+
private void incrementTimingSessionCountLocked(final int userId,
@NonNull final String packageName) {
final long now = sElapsedRealtimeClock.millis();
@@ -2689,7 +2726,8 @@ public final class QuotaController extends StateController {
@VisibleForTesting
int getProcessStateQuotaFreeThreshold(int uid) {
if (Flags.enforceQuotaPolicyToFgsJobs()
- && !CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS, uid)) {
+ && !mPlatformCompat.isChangeEnabledByUid(
+ OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS, uid)) {
return ActivityManager.PROCESS_STATE_BOUND_TOP;
}
@@ -3596,25 +3634,40 @@ public final class QuotaController extends StateController {
*/
public long EJ_GRACE_PERIOD_TOP_APP_MS = DEFAULT_EJ_GRACE_PERIOD_TOP_APP_MS;
- void adjustDefaultBucketWindowSizes() {
- ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
- ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS :
- DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
- ALLOWED_TIME_PER_PERIOD_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
- ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS :
- DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
- ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS = Flags.tuneQuotaWindowDefaultParameters()
- ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS :
- DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS;
-
- WINDOW_SIZE_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
- ? DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS :
- DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS;
- WINDOW_SIZE_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
- ? DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS :
- DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS;
- WINDOW_SIZE_WORKING_MS = DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS;
- WINDOW_SIZE_FREQUENT_MS = DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS;
+ void adjustDefaultBucketWindowSizes(boolean useLegacyQuotaConstants) {
+ if (useLegacyQuotaConstants) {
+ ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
+ DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+ ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
+ DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+ ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
+ DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS;
+
+ WINDOW_SIZE_EXEMPTED_MS = DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS;
+ WINDOW_SIZE_ACTIVE_MS = DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS;
+ WINDOW_SIZE_WORKING_MS = DEFAULT_LEGACY_WINDOW_SIZE_WORKING_MS;
+ WINDOW_SIZE_FREQUENT_MS = DEFAULT_LEGACY_WINDOW_SIZE_FREQUENT_MS;
+ } else {
+ ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
+ ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS :
+ DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+ ALLOWED_TIME_PER_PERIOD_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
+ ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS :
+ DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+ ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
+ Flags.tuneQuotaWindowDefaultParameters()
+ ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS :
+ DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS;
+
+ WINDOW_SIZE_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
+ ? DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS :
+ DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS;
+ WINDOW_SIZE_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
+ ? DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS :
+ DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS;
+ WINDOW_SIZE_WORKING_MS = DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS;
+ WINDOW_SIZE_FREQUENT_MS = DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS;
+ }
mAllowedTimePerPeriodMs[EXEMPTED_INDEX] = Math.min(MAX_PERIOD_MS,
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS));
@@ -3640,10 +3693,15 @@ public final class QuotaController extends StateController {
ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS);
}
- void adjustDefaultEjLimits() {
- EJ_LIMIT_WORKING_MS = DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS;
- EJ_TOP_APP_TIME_CHUNK_SIZE_MS = DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS;
- EJ_REWARD_INTERACTION_MS = DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS;
+ void adjustDefaultEjLimits(boolean useLegacyQuotaConstants) {
+ EJ_LIMIT_WORKING_MS = useLegacyQuotaConstants ? DEFAULT_LEGACY_EJ_LIMIT_WORKING_MS
+ : DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS;
+ EJ_TOP_APP_TIME_CHUNK_SIZE_MS = useLegacyQuotaConstants
+ ? DEFAULT_LEGACY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS :
+ DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS;
+ EJ_REWARD_INTERACTION_MS = useLegacyQuotaConstants
+ ? DEFAULT_LEGACY_EJ_REWARD_INTERACTION_MS
+ : DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS;
// The limit must be in the range [15 minutes, active limit].
mEJLimitsMs[WORKING_INDEX] = Math.max(15 * MINUTE_IN_MILLIS,
@@ -3668,6 +3726,8 @@ public final class QuotaController extends StateController {
public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
@NonNull String key) {
+ final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
switch (key) {
case KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS:
case KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS:
@@ -3835,7 +3895,8 @@ public final class QuotaController extends StateController {
case KEY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS:
// We don't need to re-evaluate execution stats or constraint status for this.
EJ_TOP_APP_TIME_CHUNK_SIZE_MS =
- properties.getLong(key, Flags.adjustQuotaDefaultConstants()
+ properties.getLong(key,
+ Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS :
DEFAULT_LEGACY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS);
// Limit chunking to be in the range [1 millisecond, 15 minutes] per event.
@@ -3873,7 +3934,8 @@ public final class QuotaController extends StateController {
case KEY_EJ_REWARD_INTERACTION_MS:
// We don't need to re-evaluate execution stats or constraint status for this.
EJ_REWARD_INTERACTION_MS =
- properties.getLong(key, Flags.adjustQuotaDefaultConstants()
+ properties.getLong(key,
+ Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS :
DEFAULT_LEGACY_EJ_REWARD_INTERACTION_MS);
// Limit interaction reward to be in the range [5 seconds, 15 minutes] per
@@ -3914,6 +3976,8 @@ public final class QuotaController extends StateController {
}
mExecutionPeriodConstantsUpdated = true;
+ final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
// Query the values as an atomic set.
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
@@ -3958,27 +4022,27 @@ public final class QuotaController extends StateController {
MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS,
DEFAULT_MAX_EXECUTION_TIME_MS);
WINDOW_SIZE_EXEMPTED_MS = properties.getLong(KEY_WINDOW_SIZE_EXEMPTED_MS,
- (Flags.adjustQuotaDefaultConstants()
+ (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
&& Flags.tuneQuotaWindowDefaultParameters())
? DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS :
- (Flags.adjustQuotaDefaultConstants()
+ (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS :
DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS));
WINDOW_SIZE_ACTIVE_MS = properties.getLong(KEY_WINDOW_SIZE_ACTIVE_MS,
- (Flags.adjustQuotaDefaultConstants()
+ (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
&& Flags.tuneQuotaWindowDefaultParameters())
? DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS :
- (Flags.adjustQuotaDefaultConstants()
+ (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS :
DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS));
WINDOW_SIZE_WORKING_MS =
properties.getLong(KEY_WINDOW_SIZE_WORKING_MS,
- Flags.adjustQuotaDefaultConstants()
+ Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS :
DEFAULT_LEGACY_WINDOW_SIZE_WORKING_MS);
WINDOW_SIZE_FREQUENT_MS =
properties.getLong(KEY_WINDOW_SIZE_FREQUENT_MS,
- Flags.adjustQuotaDefaultConstants()
+ Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS :
DEFAULT_LEGACY_WINDOW_SIZE_FREQUENT_MS);
WINDOW_SIZE_RARE_MS = properties.getLong(KEY_WINDOW_SIZE_RARE_MS,
@@ -4149,6 +4213,8 @@ public final class QuotaController extends StateController {
}
mEJLimitConstantsUpdated = true;
+ final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
// Query the values as an atomic set.
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
@@ -4163,7 +4229,7 @@ public final class QuotaController extends StateController {
EJ_LIMIT_ACTIVE_MS = properties.getLong(
KEY_EJ_LIMIT_ACTIVE_MS, DEFAULT_EJ_LIMIT_ACTIVE_MS);
EJ_LIMIT_WORKING_MS = properties.getLong(
- KEY_EJ_LIMIT_WORKING_MS, Flags.adjustQuotaDefaultConstants()
+ KEY_EJ_LIMIT_WORKING_MS, Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
? DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS :
DEFAULT_LEGACY_EJ_LIMIT_WORKING_MS);
EJ_LIMIT_FREQUENT_MS = properties.getLong(
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index a1575173ded6..3c7609e1d8ed 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -56,6 +56,7 @@ cc_binary {
"libsigchain",
"libutils",
+ "libutilscallstack",
// This is a list of libraries that need to be included in order to avoid
// bad apps. This prevents a library from having a mismatch when resolving
diff --git a/core/api/current.txt b/core/api/current.txt
index 216bbab882a9..bba21f418e41 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -24820,7 +24820,7 @@ package android.media {
method public android.view.Surface getSurface();
method public boolean isPrivacySensitive();
method public void pause() throws java.lang.IllegalStateException;
- method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
+ method @RequiresPermission(value=android.Manifest.permission.RECORD_AUDIO, conditional=true) public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
method public void registerAudioRecordingCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioRecordingCallback);
method public void release();
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
@@ -24861,7 +24861,7 @@ package android.media {
method public void setVideoProfile(@NonNull android.media.EncoderProfiles.VideoProfile);
method public void setVideoSize(int, int) throws java.lang.IllegalStateException;
method public void setVideoSource(int) throws java.lang.IllegalStateException;
- method public void start() throws java.lang.IllegalStateException;
+ method @RequiresPermission(value=android.Manifest.permission.RECORD_AUDIO, conditional=true) public void start() throws java.lang.IllegalStateException;
method public void stop() throws java.lang.IllegalStateException;
method public void unregisterAudioRecordingCallback(@NonNull android.media.AudioManager.AudioRecordingCallback);
field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 35720fd17769..2ce3609d77e7 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7354,7 +7354,15 @@ package android.media {
public class AudioDeviceVolumeManager {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public android.media.VolumeInfo getDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+ method @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+ method @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+ field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
}
public final class AudioFocusInfo implements android.os.Parcelable {
@@ -7399,7 +7407,7 @@ package android.media {
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioRecord getCallDownlinkExtractionAudioRecord(@NonNull android.media.AudioFormat);
method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioTrack getCallUplinkInjectionAudioTrack(@NonNull android.media.AudioFormat);
- method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
+ method @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public java.util.List<java.lang.Integer> getIndependentStreamTypes();
method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleStreamVolume(int);
@@ -7445,7 +7453,7 @@ package android.media {
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setBluetoothVariableLatencyEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setDeviceAsNonDefaultForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
- method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
+ method @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
@@ -7465,12 +7473,12 @@ package android.media {
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int DEVICE_CONNECTION_STATE_CONNECTED = 1; // 0x1
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int DEVICE_CONNECTION_STATE_DISCONNECTED = 0; // 0x0
- field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
- field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
- field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
- field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
- field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
- field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+ field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
field public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
field public static final String EXTRA_VOLUME_STREAM_VALUE = "android.media.EXTRA_VOLUME_STREAM_VALUE";
field public static final int FLAG_BLUETOOTH_ABS_VOLUME = 64; // 0x40
@@ -19263,7 +19271,6 @@ package android.webkit {
method @Deprecated public abstract void setUseWebViewBackgroundForOverscrollBackground(boolean);
method @Deprecated public abstract void setUserAgent(int);
method public abstract void setVideoOverlayForEmbeddedEncryptedVideoEnabled(boolean);
- field @FlaggedApi("android.webkit.enable_chips") public static final long ENABLE_CHIPS = 380890146L; // 0x16b3ec22L
field public static final long ENABLE_SIMPLIFIED_DARK_MODE = 214741472L; // 0xcccb1e0L
field @FlaggedApi("android.webkit.user_agent_reduction") public static final long ENABLE_USER_AGENT_REDUCTION = 371034303L; // 0x161d88bfL
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4c8283907712..daa1902edf02 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1955,6 +1955,10 @@ package android.media {
method public static void enforceValidAudioDeviceTypeOut(int);
}
+ public class AudioDeviceVolumeManager {
+ method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
+ }
+
public final class AudioFocusRequest {
method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
}
@@ -2010,7 +2014,6 @@ package android.media {
method @NonNull public android.media.VolumePolicy getVolumePolicy();
method public boolean hasRegisteredDynamicPolicy();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isCsdEnabled();
- method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
method @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public boolean isPstnCallAudioInterceptable();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isVolumeControlUsingVolumeGroups();
method public void permissionUpdateBarrier();
diff --git a/core/java/android/app/AppCompatTaskInfo.java b/core/java/android/app/AppCompatTaskInfo.java
index 3fd9d8b26611..85621c9c3fab 100644
--- a/core/java/android/app/AppCompatTaskInfo.java
+++ b/core/java/android/app/AppCompatTaskInfo.java
@@ -136,7 +136,7 @@ public class AppCompatTaskInfo implements Parcelable {
private static final int FLAGS_ORGANIZER_INTERESTED = FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP
| FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON | FLAG_FULLSCREEN_OVERRIDE_SYSTEM
| FLAG_FULLSCREEN_OVERRIDE_USER | FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE
- | FLAG_OPT_OUT_EDGE_TO_EDGE;
+ | FLAG_OPT_OUT_EDGE_TO_EDGE | FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE;
@TopActivityFlag
private static final int FLAGS_COMPAT_UI_INTERESTED = FLAGS_ORGANIZER_INTERESTED
@@ -179,7 +179,8 @@ public class AppCompatTaskInfo implements Parcelable {
*/
public boolean hasCompatUI() {
return isTopActivityInSizeCompat() || eligibleForLetterboxEducation()
- || isLetterboxDoubleTapEnabled() || eligibleForUserAspectRatioButton();
+ || isLetterboxDoubleTapEnabled() || eligibleForUserAspectRatioButton()
+ || isRestartMenuEnabledForDisplayMove();
}
/**
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 2e8031dd22fe..2559bd036039 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -231,9 +231,9 @@ public final class ApplicationStartInfo implements Parcelable {
public static final int START_COMPONENT_OTHER = 5;
/**
- * @see #getMonoticCreationTimeMs
+ * @see #getMonotonicCreationTimeMs
*/
- private long mMonoticCreationTimeMs;
+ private long mMonotonicCreationTimeMs;
/**
* @see #getStartupState
@@ -545,8 +545,8 @@ public final class ApplicationStartInfo implements Parcelable {
*
* @hide
*/
- public long getMonoticCreationTimeMs() {
- return mMonoticCreationTimeMs;
+ public long getMonotonicCreationTimeMs() {
+ return mMonotonicCreationTimeMs;
}
/**
@@ -751,14 +751,14 @@ public final class ApplicationStartInfo implements Parcelable {
dest.writeParcelable(mStartIntent, flags);
dest.writeInt(mLaunchMode);
dest.writeBoolean(mWasForceStopped);
- dest.writeLong(mMonoticCreationTimeMs);
+ dest.writeLong(mMonotonicCreationTimeMs);
dest.writeInt(mStartComponent);
}
// LINT.ThenChange(:read_parcel)
/** @hide */
public ApplicationStartInfo(long monotonicCreationTimeMs) {
- mMonoticCreationTimeMs = monotonicCreationTimeMs;
+ mMonotonicCreationTimeMs = monotonicCreationTimeMs;
}
/** @hide */
@@ -776,7 +776,7 @@ public final class ApplicationStartInfo implements Parcelable {
mStartIntent = other.mStartIntent;
mLaunchMode = other.mLaunchMode;
mWasForceStopped = other.mWasForceStopped;
- mMonoticCreationTimeMs = other.mMonoticCreationTimeMs;
+ mMonotonicCreationTimeMs = other.mMonotonicCreationTimeMs;
mStartComponent = other.mStartComponent;
}
@@ -803,7 +803,7 @@ public final class ApplicationStartInfo implements Parcelable {
in.readParcelable(Intent.class.getClassLoader(), android.content.Intent.class);
mLaunchMode = in.readInt();
mWasForceStopped = in.readBoolean();
- mMonoticCreationTimeMs = in.readLong();
+ mMonotonicCreationTimeMs = in.readLong();
mStartComponent = in.readInt();
}
// LINT.ThenChange(:write_parcel)
@@ -887,7 +887,7 @@ public final class ApplicationStartInfo implements Parcelable {
}
proto.write(ApplicationStartInfoProto.LAUNCH_MODE, mLaunchMode);
proto.write(ApplicationStartInfoProto.WAS_FORCE_STOPPED, mWasForceStopped);
- proto.write(ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS, mMonoticCreationTimeMs);
+ proto.write(ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS, mMonotonicCreationTimeMs);
proto.write(ApplicationStartInfoProto.START_COMPONENT, mStartComponent);
proto.end(token);
}
@@ -980,7 +980,7 @@ public final class ApplicationStartInfo implements Parcelable {
ApplicationStartInfoProto.WAS_FORCE_STOPPED);
break;
case (int) ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS:
- mMonoticCreationTimeMs = proto.readLong(
+ mMonotonicCreationTimeMs = proto.readLong(
ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS);
break;
case (int) ApplicationStartInfoProto.START_COMPONENT:
@@ -999,7 +999,7 @@ public final class ApplicationStartInfo implements Parcelable {
sb.append(prefix)
.append("ApplicationStartInfo ").append(seqSuffix).append(':')
.append('\n')
- .append(" monotonicCreationTimeMs=").append(mMonoticCreationTimeMs)
+ .append(" monotonicCreationTimeMs=").append(mMonotonicCreationTimeMs)
.append('\n')
.append(" pid=").append(mPid)
.append(" realUid=").append(mRealUid)
@@ -1094,7 +1094,7 @@ public final class ApplicationStartInfo implements Parcelable {
&& TextUtils.equals(mProcessName, o.mProcessName)
&& timestampsEquals(o)
&& mWasForceStopped == o.mWasForceStopped
- && mMonoticCreationTimeMs == o.mMonoticCreationTimeMs
+ && mMonotonicCreationTimeMs == o.mMonotonicCreationTimeMs
&& mStartComponent == o.mStartComponent;
}
@@ -1102,7 +1102,7 @@ public final class ApplicationStartInfo implements Parcelable {
public int hashCode() {
return Objects.hash(mPid, mRealUid, mPackageUid, mDefiningUid, mReason, mStartupState,
mStartType, mLaunchMode, mPackageName, mProcessName, mStartupTimestampsNs,
- mMonoticCreationTimeMs, mStartComponent);
+ mMonotonicCreationTimeMs, mStartComponent);
}
private boolean timestampsEquals(@NonNull ApplicationStartInfo other) {
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 6efc4ef55180..3003b79435e2 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -49,11 +49,14 @@ import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.compat.CompatChanges;
import android.app.role.RoleManager;
+import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.Overridable;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.PermissionChecker;
import android.content.pm.PackageManager;
@@ -67,6 +70,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.permission.PermissionCheckerManager;
+import android.permission.PermissionManager;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -1174,17 +1178,48 @@ public abstract class ForegroundServiceTypePolicy {
@PackageManager.PermissionResult
public int checkPermission(@NonNull Context context, int callerUid, int callerPid,
String packageName, boolean allowWhileInUse) {
- return checkPermission(context, mName, callerUid, callerPid, packageName,
- allowWhileInUse);
+ int permissionResult = checkPermission(context, mName, callerUid, callerPid,
+ packageName, allowWhileInUse, Context.DEVICE_ID_DEFAULT);
+
+ if (permissionResult == PERMISSION_GRANTED
+ || !PermissionManager.DEVICE_AWARE_PERMISSIONS.contains(mName)) {
+ return permissionResult;
+ }
+
+ // For device aware permissions, check if the permission is granted on any other
+ // active virtual device
+ VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class);
+ if (vdm == null) {
+ return permissionResult;
+ }
+
+ final List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
+ for (int i = 0, size = virtualDevices.size(); i < size; i++) {
+ final VirtualDevice virtualDevice = virtualDevices.get(i);
+ int resolvedDeviceId = PermissionManager.resolveDeviceIdForPermissionCheck(
+ context, virtualDevice.getDeviceId(), mName);
+ // we already checked on the default device context
+ if (resolvedDeviceId == Context.DEVICE_ID_DEFAULT) {
+ continue;
+ }
+ permissionResult = checkPermission(context, mName, callerUid, callerPid,
+ packageName, allowWhileInUse, resolvedDeviceId);
+ if (permissionResult == PERMISSION_GRANTED) {
+ break;
+ }
+ }
+
+ return permissionResult;
}
@SuppressLint("AndroidFrameworkRequiresPermission")
@PackageManager.PermissionResult
int checkPermission(@NonNull Context context, @NonNull String name, int callerUid,
- int callerPid, String packageName, boolean allowWhileInUse) {
+ int callerPid, String packageName, boolean allowWhileInUse, int deviceId) {
+ final AttributionSource attributionSource = new AttributionSource(callerUid,
+ packageName, null /*attributionTag*/, deviceId);
@PermissionCheckerManager.PermissionResult final int result =
- PermissionChecker.checkPermissionForPreflight(context, name,
- callerPid, callerUid, packageName);
+ PermissionChecker.checkPermissionForPreflight(context, name, attributionSource);
if (result == PERMISSION_HARD_DENIED) {
// If the user didn't grant this permission at all.
return PERMISSION_DENIED;
@@ -1196,7 +1231,7 @@ public abstract class ForegroundServiceTypePolicy {
? PERMISSION_GRANTED : PERMISSION_DENIED;
}
final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
- final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, callerUid, packageName);
+ final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, attributionSource);
switch (mode) {
case MODE_ALLOWED:
// The appop is just allowed, plain and simple.
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 38141cf20ce3..6e495768bfd4 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -1417,7 +1417,36 @@ public class PropertyInvalidatedCache<Query, Result> {
}
/**
- * Enable or disable testing. The protocol requires that the mode toggle: for instance, it is
+ * Throw if the current process is not allowed to use test APIs.
+ */
+ @android.ravenwood.annotation.RavenwoodReplace
+ private static void throwIfNotTest() {
+ final ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ // Only tests can reach here.
+ return;
+ }
+ final Instrumentation instrumentation = activityThread.getInstrumentation();
+ if (instrumentation == null) {
+ // Only tests can reach here.
+ return;
+ }
+ if (instrumentation.isInstrumenting()) {
+ return;
+ }
+ if (Flags.enforcePicTestmodeProtocol()) {
+ throw new IllegalStateException("Test-only API called not from a test.");
+ }
+ }
+
+ /**
+ * Do not throw if running under ravenwood.
+ */
+ private static void throwIfNotTest$ravenwood() {
+ }
+
+ /**
+ * Enable or disable test mode. The protocol requires that the mode toggle: for instance, it is
* illegal to clear the test mode if the test mode is already off. Enabling test mode puts
* all caches in the process into test mode; all nonces are initialized to UNSET and
* subsequent reads and writes are to process memory. This has the effect of disabling all
@@ -1425,10 +1454,12 @@ public class PropertyInvalidatedCache<Query, Result> {
* operation.
* @param mode The desired test mode.
* @throws IllegalStateException if the supplied mode is already set.
+ * @throws IllegalStateException if the process is not running an instrumentation test.
* @hide
*/
@VisibleForTesting
public static void setTestMode(boolean mode) {
+ throwIfNotTest();
synchronized (sGlobalLock) {
if (sTestMode == mode) {
final String msg = "cannot set test mode redundantly: mode=" + mode;
@@ -1464,9 +1495,11 @@ public class PropertyInvalidatedCache<Query, Result> {
* for which it would not otherwise have permission. Caches in test mode do NOT write their
* values to the system properties. The effect is local to the current process. Test mode
* must be true when this method is called.
+ * @throws IllegalStateException if the process is not running an instrumentation test.
* @hide
*/
public void testPropertyName() {
+ throwIfNotTest();
synchronized (sGlobalLock) {
if (sTestMode == false) {
throw new IllegalStateException("cannot test property name with test mode off");
@@ -1777,10 +1810,12 @@ public class PropertyInvalidatedCache<Query, Result> {
* When multiple caches share a single property value, using an instance method on one of
* the cache objects to invalidate all of the cache objects becomes confusing and you should
* just use the static version of this function.
+ * @throws IllegalStateException if the process is not running an instrumentation test.
* @hide
*/
@VisibleForTesting
public void disableSystemWide() {
+ throwIfNotTest();
disableSystemWide(mPropertyName);
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 957482450893..e8d2e2871ef2 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -20,6 +20,7 @@ import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
import static android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT;
import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+import static android.app.Flags.enableConnectedDisplaysWallpaper;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
@@ -248,7 +249,9 @@ public class WallpaperManager {
/**
* Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
* starts going away.
- * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}.
+ * <p>
+ * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}
+ * or by {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
*
* @hide
*/
@@ -256,6 +259,18 @@ public class WallpaperManager {
"android.wallpaper.keyguardgoingaway";
/**
+ * Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
+ * starts going away.
+ *
+ * <p>This command is triggered by
+ * {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
+ *
+ * @hide
+ */
+ public static final String COMMAND_KEYGUARD_APPEARING =
+ "android.wallpaper.keyguardappearing";
+
+ /**
* Command for {@link #sendWallpaperCommand}: reported by System UI when the device is going to
* sleep. The x and y arguments are a location (possibly very roughly) corresponding to the
* action that caused the device to go to sleep. For example, if the power button was pressed,
@@ -860,7 +875,13 @@ public class WallpaperManager {
return null;
}
try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
- ImageDecoder.Source src = ImageDecoder.createSource(context.getResources(), is);
+ ImageDecoder.Source src;
+ if (enableConnectedDisplaysWallpaper()) {
+ src = ImageDecoder.createSource(context.getResources(), is,
+ /* density= */ 0);
+ } else {
+ src = ImageDecoder.createSource(context.getResources(), is);
+ }
return ImageDecoder.decodeBitmap(src, ((decoder, info, source) -> {
// Mutable and hardware config can't be set at the same time.
decoder.setMutableRequired(!hardware);
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index c6d0f61b529e..8c99bd8e2ed9 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -790,12 +790,6 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
|| mWindowingMode == WINDOWING_MODE_MULTI_WINDOW;
}
- /** Returns true if the task bounds should persist across power cycles.
- * @hide */
- public boolean persistTaskBounds() {
- return mWindowingMode == WINDOWING_MODE_FREEFORM;
- }
-
/**
* Returns true if the tasks associated with this window configuration are floating.
* Floating tasks are laid out differently as they are allowed to extend past the display bounds
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index e431426d5d09..a26bfa4f586c 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -170,3 +170,30 @@ flag {
description: "Holdback study for jank_perceptible_narrow"
bug: "304837972"
}
+
+flag {
+ namespace: "system_performance"
+ name: "app_start_info_cleanup_old_records"
+ description: "Cleanup old records to reduce size of in memory store."
+ bug: "384539178"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ namespace: "system_performance"
+ name: "app_start_info_keep_records_sorted"
+ description: "Ensure records are kept sorted to avoid extra work"
+ bug: "384539178"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "enable_process_observer_broadcast_on_process_started"
+ namespace: "system_performance"
+ description: "Enable ProcessObserver's onProcessStarted callbacks."
+ bug: "323959187"
+}
diff --git a/core/java/android/app/wallpaper.aconfig b/core/java/android/app/wallpaper.aconfig
index 7aba172fad79..4a15a723da1a 100644
--- a/core/java/android/app/wallpaper.aconfig
+++ b/core/java/android/app/wallpaper.aconfig
@@ -24,6 +24,16 @@ flag {
}
flag {
+ name: "notify_keyguard_events"
+ namespace: "systemui"
+ description: "Send keyguard showing/hiding/going-away events to wallpaper as wallpaper commands (guarded by permission)"
+ bug: "395897130"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "accurate_wallpaper_downsampling"
namespace: "systemui"
description: "Accurate downsampling of wallpaper bitmap for high resolution images"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index bb62ac321202..a253613e060c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -680,6 +680,7 @@ public class Intent implements Parcelable, Cloneable {
private static final String ATTR_COMPONENT = "component";
private static final String ATTR_DATA = "data";
private static final String ATTR_FLAGS = "flags";
+ private static final String ATTR_PACKAGE = "package";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
@@ -12893,6 +12894,9 @@ public class Intent implements Parcelable, Cloneable {
if (mComponent != null) {
out.attribute(null, ATTR_COMPONENT, mComponent.flattenToShortString());
}
+ if (android.content.flags.Flags.intentSaveToXmlPackage() && mPackage != null) {
+ out.attribute(null, ATTR_PACKAGE, mPackage);
+ }
out.attribute(null, ATTR_FLAGS, Integer.toHexString(getFlags()));
if (mCategories != null) {
@@ -12926,6 +12930,9 @@ public class Intent implements Parcelable, Cloneable {
intent.setComponent(ComponentName.unflattenFromString(attrValue));
} else if (ATTR_FLAGS.equals(attrName)) {
intent.setFlags(Integer.parseInt(attrValue, 16));
+ } else if (android.content.flags.Flags.intentSaveToXmlPackage()
+ && ATTR_PACKAGE.equals(attrName)) {
+ intent.setPackage(attrValue);
} else {
Log.e(TAG, "restoreFromXml: unknown attribute=" + attrName);
}
diff --git a/core/java/android/content/flags/flags.aconfig b/core/java/android/content/flags/flags.aconfig
index aac04b3a9d15..148532b62c36 100644
--- a/core/java/android/content/flags/flags.aconfig
+++ b/core/java/android/content/flags/flags.aconfig
@@ -7,4 +7,14 @@ flag {
namespace: "machine_learning"
description: "This flag enables the newly added flag for binding package-private isolated processes."
bug: "312706530"
-} \ No newline at end of file
+}
+
+flag {
+ namespace: "system_performance"
+ name: "intent_save_to_xml_package"
+ description: "Add package to saveToXml so save then restore passes filterEquals."
+ bug: "369856202"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 53203eba4020..c5412a982110 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -494,10 +494,14 @@ public class UserInfo implements Parcelable {
// TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType))
/* @hide */
public boolean canHaveProfile() {
- if (isProfile() || isGuest() || isRestricted()) {
+ if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) {
return false;
}
- return isMain();
+ // NOTE: profiles used to be restricted just to the system user (and later to the main
+ // user), but from the framework point of view there is no need for such restriction, hence
+ // it's lifted
+ // TODO(b/374832167): check value of config_supportProfilesOnNonMainUser
+ return isMain() || android.multiuser.Flags.profilesForAll();
}
// TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible.
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 3411a4897e83..3dbd5b239ae5 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -646,3 +646,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "profiles_for_all"
+ namespace: "multiuser"
+ description: "Allows any regular user to have profiles"
+ bug: "374832167"
+}
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index a7fbce51e9df..7dc6afba3f1c 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -188,24 +188,6 @@ public interface BiometricConstants {
int BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON = 22;
/**
- * The error code returned after lock out error happens, the error dialog shows, and the users
- * dismisses the dialog. This is a placeholder that is currently only used by the support
- * library.
- *
- * @hide
- */
- int BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED = 23;
-
- /**
- * The error code returned after biometric hardware error happens, the error dialog shows, and
- * the users dismisses the dialog.This is a placeholder that is currently only used by the
- * support library.
- *
- * @hide
- */
- int BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED = 24;
-
- /**
* This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
* because the authentication attempt was unsuccessful.
* @hide
@@ -237,8 +219,6 @@ public interface BiometricConstants {
BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON,
- BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED,
- BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED,
BIOMETRIC_PAUSED_REJECTED})
@Retention(RetentionPolicy.SOURCE)
@interface Errors {}
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 4815f3e4f524..061e6f44c9c7 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -64,3 +64,11 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "move_fm_api_to_bm"
+ is_exported: true
+ namespace: "biometrics_framework"
+ description: "Feature flag for moving some FingerprintManager APIs to BiometricManager to unblock FM removal."
+ bug: "323957939"
+}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 2e7bc6d9b9f7..84d96bd1e155 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -3504,6 +3504,10 @@ public class InputMethodService extends AbstractInputMethodService {
mInlineSuggestionSessionController.notifyOnStartInputView();
onStartInputView(mInputEditorInfo, restarting);
startExtractingText(true);
+ // Back callback is typically registered in {@link #showWindow()}, but it's possible
+ // for {@link #doStartInput()} to be called without {@link #showWindow()} so we also
+ // register here.
+ registerDefaultOnBackInvokedCallback();
} else if (mCandidatesVisibility == View.VISIBLE) {
if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
mCandidatesViewStarted = true;
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index f420b5d7b886..7da053d0010e 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -236,7 +236,12 @@ final class NavigationBarController {
systemInsets.bottom, Gravity.BOTTOM));
mLastInsets = systemInsets;
} else {
- decorView.addView(mNavigationBarFrame);
+ // If systemInsets are null, the DecorView is not attached to the window yet.
+ // Use the final captionBar height as the initial one, otherwise it resolves to
+ // match parent, and can lead to full size IME insets.
+ final int height = getImeCaptionBarHeight(true /* imeDrawsImeNavBar */);
+ decorView.addView(mNavigationBarFrame, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, height, Gravity.BOTTOM));
}
final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
NavigationBarView.class::isInstance);
@@ -461,7 +466,7 @@ final class NavigationBarController {
final Insets systemInsets = getSystemInsets();
if (systemInsets != null) {
if (!Objects.equals(systemInsets, mLastInsets)) {
- mNavigationBarFrame.setLayoutParams(new NavigationBarFrame.LayoutParams(
+ mNavigationBarFrame.setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
systemInsets.bottom, Gravity.BOTTOM));
mLastInsets = systemInsets;
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ee62dea7f9e5..6b1e918a3c47 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -149,6 +149,11 @@ public class Binder implements IBinder {
private static volatile boolean sStackTrackingEnabled = false;
/**
+ * The extension binder object
+ */
+ private IBinder mExtension = null;
+
+ /**
* Enable Binder IPC stack tracking. If enabled, every binder transaction will be logged to
* {@link TransactionTracker}.
*
@@ -1237,7 +1242,9 @@ public class Binder implements IBinder {
/** @hide */
@Override
- public final native @Nullable IBinder getExtension();
+ public final @Nullable IBinder getExtension() {
+ return mExtension;
+ }
/**
* Set the binder extension.
@@ -1245,7 +1252,12 @@ public class Binder implements IBinder {
*
* @hide
*/
- public final native void setExtension(@Nullable IBinder extension);
+ public final void setExtension(@Nullable IBinder extension) {
+ mExtension = extension;
+ setExtensionNative(extension);
+ }
+
+ private final native void setExtensionNative(@Nullable IBinder extension);
/**
* Default implementation rewinds the parcels and calls onTransact. On
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
index 2e7c3be53d90..07a7f8b50f20 100644
--- a/core/java/android/os/IpcDataCache.java
+++ b/core/java/android/os/IpcDataCache.java
@@ -718,7 +718,7 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query,
}
/**
- * Enable or disable testing. The protocol requires that the mode toggle: for instance, it is
+ * Enable or disable test mode. The protocol requires that the mode toggle: for instance, it is
* illegal to clear the test mode if the test mode is already off. Enabling test mode puts
* all caches in the process into test mode; all nonces are initialized to UNSET and
* subsequent reads and writes are to process memory. This has the effect of disabling all
@@ -726,6 +726,7 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query,
* operation.
* @param mode The desired test mode.
* @throws IllegalStateException if the supplied mode is already set.
+ * @throws IllegalStateException if the process is not running an instrumentation test.
* @hide
*/
@TestApi
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 62b2bcf32442..cb2b13d1e120 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -349,7 +349,8 @@ public final class AdvancedProtectionManager {
*
* @param featureId The feature identifier.
* @param type The type of the feature describing the action that needs to be explained
- * in the dialog or null for default explanation.
+ * in the dialog or {@link #SUPPORT_DIALOG_TYPE_UNKNOWN} for default
+ * explanation.
* @return Intent An intent to be used to start the dialog-activity that explains a feature was
* disabled by advanced protection.
* @hide
@@ -373,7 +374,27 @@ public final class AdvancedProtectionManager {
return intent;
}
- /** @hide */
+ /**
+ * Called by a feature to display a support dialog when a feature was disabled by advanced
+ * protection based on a policy identifier or restriction. This returns an intent that can be
+ * used with {@link Context#startActivity(Intent)} to display the dialog.
+ *
+ * <p>At the moment, if the dialog is for {@link #FEATURE_ID_DISALLOW_CELLULAR_2G} or
+ * {@link #FEATURE_ID_ENABLE_MTE} and the provided type is
+ * {@link #SUPPORT_DIALOG_TYPE_UNKNOWN}, the type will be changed to
+ * {@link #SUPPORT_DIALOG_TYPE_DISABLED_SETTING} in the returned intent, as these features only
+ * have a disabled setting UI.
+ *
+ * <p>Note that this method doesn't check if the feature is actually disabled, i.e. this method
+ * will always return an intent.
+ *
+ * @param identifier The policy identifier or restriction.
+ * @param type The type of the feature describing the action that needs to be explained
+ * in the dialog or {@link #SUPPORT_DIALOG_TYPE_UNKNOWN} for default
+ * explanation.
+ * @return Intent An intent to be used to start the dialog-activity that explains a feature was
+ * disabled by advanced protection.
+ * @hide */
public static @NonNull Intent createSupportIntentForPolicyIdentifierOrRestriction(
@NonNull String identifier, @SupportDialogType int type) {
Objects.requireNonNull(identifier);
@@ -382,16 +403,21 @@ public final class AdvancedProtectionManager {
+ " SUPPORT_DIALOG_TYPE_* APIs.");
}
final int featureId;
+ int dialogType = type;
if (DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY.equals(identifier)) {
featureId = FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
} else if (DISALLOW_CELLULAR_2G.equals(identifier)) {
featureId = FEATURE_ID_DISALLOW_CELLULAR_2G;
+ dialogType = (dialogType == SUPPORT_DIALOG_TYPE_UNKNOWN)
+ ? SUPPORT_DIALOG_TYPE_DISABLED_SETTING : dialogType;
} else if (MEMORY_TAGGING_POLICY.equals(identifier)) {
featureId = FEATURE_ID_ENABLE_MTE;
+ dialogType = (dialogType == SUPPORT_DIALOG_TYPE_UNKNOWN)
+ ? SUPPORT_DIALOG_TYPE_DISABLED_SETTING : dialogType;
} else {
throw new UnsupportedOperationException("Unsupported identifier: " + identifier);
}
- return createSupportIntent(featureId, type);
+ return createSupportIntent(featureId, dialogType);
}
/** @hide */
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 9fd4618bc5da..0a922d61a786 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -97,10 +97,13 @@ flag {
}
flag {
- name: "clear_strong_auth_on_add_primary_credential"
+ name: "clear_strong_auth_on_adding_primary_credential"
namespace: "biometrics"
- description: "Clear StrongAuth on add credential"
+ description: "Clear StrongAuth on adding credential"
bug: "320817991"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 6b7b81887706..7e9dfe6d972a 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1030,10 +1030,18 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
handlePendingControlRequest(statsToken);
} else {
if (showTypes[0] != 0) {
+ if ((showTypes[0] & ime()) != 0) {
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+ }
applyAnimation(showTypes[0], true /* show */, false /* fromIme */,
false /* skipsCallbacks */, statsToken);
}
if (hideTypes[0] != 0) {
+ if ((hideTypes[0] & ime()) != 0) {
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+ }
applyAnimation(hideTypes[0], false /* show */, false /* fromIme */,
// The animation of hiding transient types shouldn't be detected by the
// app. Otherwise, it might be able to react to the callbacks and cause
@@ -1041,6 +1049,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
(hideTypes[0] & ~transientTypes[0]) == 0 /* skipsCallbacks */,
statsToken);
}
+ if ((showTypes[0] & ime()) == 0 && (hideTypes[0] & ime()) == 0) {
+ ImeTracker.forLogging().onCancelled(statsToken,
+ ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+ }
}
} else {
if (showTypes[0] != 0) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1b57b0045537..94e9aa709369 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1070,9 +1070,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
if (mSurfacePackage != null) {
- mSurfaceControlViewHostParent.detach();
mEmbeddedWindowParams.clear();
if (releaseSurfacePackage) {
+ mSurfaceControlViewHostParent.detach();
mSurfacePackage.release();
mSurfacePackage = null;
}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 624216776f42..b97f28da7559 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -329,13 +329,17 @@ public final class WindowManagerGlobal {
/**
* Adds a listener that will be notified whenever {@link #getWindowViews()} changes. The
- * current value is provided immediately. If it was registered previously then this is ano op.
+ * current value is provided immediately using the provided {@link Executor}. If this
+ * {@link Consumer} was registered previously, then this is a no op.
*/
public void addWindowViewsListener(@NonNull Executor executor,
@NonNull Consumer<List<View>> consumer) {
synchronized (mLock) {
+ if (mWindowViewsListenerGroup.isConsumerPresent(consumer)) {
+ return;
+ }
mWindowViewsListenerGroup.addListener(executor, consumer);
- mWindowViewsListenerGroup.accept(getWindowViews());
+ executor.execute(() -> consumer.accept(getWindowViews()));
}
}
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 5dadf32d2a36..b1ba8b32d2f4 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -231,6 +231,7 @@ public interface ImeTracker {
PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED,
PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED,
PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES,
+ PHASE_CLIENT_ON_CONTROLS_CHANGED,
})
@Retention(RetentionPolicy.SOURCE)
@interface Phase {}
@@ -469,6 +470,9 @@ public interface ImeTracker {
/** The control target reported its animatingTypes back to WindowManagerService. */
int PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES =
ImeProtoEnums.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES;
+ /** InsetsController received a control for the IME. */
+ int PHASE_CLIENT_ON_CONTROLS_CHANGED =
+ ImeProtoEnums.PHASE_CLIENT_ON_CONTROLS_CHANGED;
/**
* Called when an IME request is started.
diff --git a/core/java/android/view/inspector/WindowInspector.java b/core/java/android/view/inspector/WindowInspector.java
index 3ebca3c9d9b6..f0cc01133e07 100644
--- a/core/java/android/view/inspector/WindowInspector.java
+++ b/core/java/android/view/inspector/WindowInspector.java
@@ -42,8 +42,9 @@ public final class WindowInspector {
}
/**
- * Adds a listener that is notified whenever the list of global window views changes. If a
- * {@link Consumer} is already registered this method is a no op.
+ * Adds a listener that is notified whenever the value of {@link #getGlobalWindowViews()}
+ * changes. The current value is provided immediately using the provided {@link Executor}.
+ * If this {@link Consumer} is already registered, then this method is a no op.
* @see #getGlobalWindowViews()
*/
@FlaggedApi(android.view.flags.Flags.FLAG_ROOT_VIEW_CHANGED_LISTENER)
diff --git a/core/java/android/view/translation/ListenerGroup.java b/core/java/android/view/translation/ListenerGroup.java
index bf506815f841..5c70805042fa 100644
--- a/core/java/android/view/translation/ListenerGroup.java
+++ b/core/java/android/view/translation/ListenerGroup.java
@@ -48,7 +48,7 @@ public class ListenerGroup<T> {
* is a no op.
*/
public void addListener(@NonNull Executor executor, @NonNull Consumer<T> consumer) {
- if (isContained(consumer)) {
+ if (isConsumerPresent(consumer)) {
return;
}
mListeners.add(new ListenerWrapper<>(executor, consumer));
@@ -69,7 +69,7 @@ public class ListenerGroup<T> {
* Returns {@code true} if the {@link Consumer} is present in the list, {@code false}
* otherwise.
*/
- private boolean isContained(Consumer<T> consumer) {
+ public boolean isConsumerPresent(Consumer<T> consumer) {
return computeIndex(consumer) > -1;
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index ab7a4f289d73..ed3f2d12ac78 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1789,17 +1789,4 @@ public abstract class WebSettings {
* @see #setDisabledActionModeMenuItems
*/
public static final int MENU_ITEM_PROCESS_TEXT = 1 << 2;
-
- /**
- * Enable CHIPS for webview.
- * This provides a means to check if partitioned cookies are enabled by default.
- * CHIPS will only be enabled by default for apps targeting Android B or above.
- *
- * @hide
- */
- @ChangeId
- @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM)
- @FlaggedApi(android.webkit.Flags.FLAG_ENABLE_CHIPS)
- @SystemApi
- public static final long ENABLE_CHIPS = 380890146L;
}
diff --git a/core/java/android/webkit/flags.aconfig b/core/java/android/webkit/flags.aconfig
index 16cbb8abc9d6..c5176a2f1f15 100644
--- a/core/java/android/webkit/flags.aconfig
+++ b/core/java/android/webkit/flags.aconfig
@@ -36,14 +36,6 @@ flag {
}
flag {
- name: "enable_chips"
- is_exported: true
- namespace: "webview"
- description: "New feature enable CHIPS for webview"
- bug: "359448044"
-}
-
-flag {
name: "file_system_access"
is_exported: true
namespace: "webview"
diff --git a/core/java/android/window/BackMotionEvent.java b/core/java/android/window/BackMotionEvent.java
index d53c787749d9..cc2afbc6aaa3 100644
--- a/core/java/android/window/BackMotionEvent.java
+++ b/core/java/android/window/BackMotionEvent.java
@@ -18,6 +18,7 @@ package android.window;
import android.annotation.FloatRange;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.RemoteAnimationTarget;
@@ -38,6 +39,8 @@ public final class BackMotionEvent implements Parcelable {
@BackEvent.SwipeEdge
private final int mSwipeEdge;
+ @Nullable
+ private final RemoteAnimationTarget mDepartingAnimationTarget;
/**
* Creates a new {@link BackMotionEvent} instance.
@@ -50,6 +53,8 @@ public final class BackMotionEvent implements Parcelable {
* @param progress Value between 0 and 1 on how far along the back gesture is.
* @param triggerBack Indicates whether the back arrow is in the triggered state or not
* @param swipeEdge Indicates which edge the swipe starts from.
+ * @param departingAnimationTarget The remote animation target of the departing
+ * application window.
*/
public BackMotionEvent(
float touchX,
@@ -57,13 +62,15 @@ public final class BackMotionEvent implements Parcelable {
long frameTimeMillis,
float progress,
boolean triggerBack,
- @BackEvent.SwipeEdge int swipeEdge) {
+ @BackEvent.SwipeEdge int swipeEdge,
+ @Nullable RemoteAnimationTarget departingAnimationTarget) {
mTouchX = touchX;
mTouchY = touchY;
mFrameTimeMillis = frameTimeMillis;
mProgress = progress;
mTriggerBack = triggerBack;
mSwipeEdge = swipeEdge;
+ mDepartingAnimationTarget = departingAnimationTarget;
}
private BackMotionEvent(@NonNull Parcel in) {
@@ -72,6 +79,7 @@ public final class BackMotionEvent implements Parcelable {
mProgress = in.readFloat();
mTriggerBack = in.readBoolean();
mSwipeEdge = in.readInt();
+ mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
mFrameTimeMillis = in.readLong();
}
@@ -100,6 +108,7 @@ public final class BackMotionEvent implements Parcelable {
dest.writeFloat(mProgress);
dest.writeBoolean(mTriggerBack);
dest.writeInt(mSwipeEdge);
+ dest.writeTypedObject(mDepartingAnimationTarget, flags);
dest.writeLong(mFrameTimeMillis);
}
@@ -151,6 +160,16 @@ public final class BackMotionEvent implements Parcelable {
return mFrameTimeMillis;
}
+ /**
+ * Returns the {@link RemoteAnimationTarget} of the top departing application window,
+ * or {@code null} if the top window should not be moved for the current type of back
+ * destination.
+ */
+ @Nullable
+ public RemoteAnimationTarget getDepartingAnimationTarget() {
+ return mDepartingAnimationTarget;
+ }
+
@Override
public String toString() {
return "BackMotionEvent{"
@@ -160,6 +179,7 @@ public final class BackMotionEvent implements Parcelable {
+ ", mProgress=" + mProgress
+ ", mTriggerBack=" + mTriggerBack
+ ", mSwipeEdge=" + mSwipeEdge
+ + ", mDepartingAnimationTarget=" + mDepartingAnimationTarget
+ "}";
}
}
diff --git a/core/java/android/window/BackTouchTracker.java b/core/java/android/window/BackTouchTracker.java
index ea1b64066cfe..4908068d51e4 100644
--- a/core/java/android/window/BackTouchTracker.java
+++ b/core/java/android/window/BackTouchTracker.java
@@ -20,6 +20,7 @@ import android.annotation.FloatRange;
import android.os.SystemProperties;
import android.util.MathUtils;
import android.view.MotionEvent;
+import android.view.RemoteAnimationTarget;
import java.io.PrintWriter;
@@ -146,14 +147,15 @@ public class BackTouchTracker {
}
/** Creates a start {@link BackMotionEvent}. */
- public BackMotionEvent createStartEvent() {
+ public BackMotionEvent createStartEvent(RemoteAnimationTarget target) {
return new BackMotionEvent(
/* touchX = */ mInitTouchX,
/* touchY = */ mInitTouchY,
/* frameTimeMillis = */ 0,
/* progress = */ 0,
/* triggerBack = */ mTriggerBack,
- /* swipeEdge = */ mSwipeEdge);
+ /* swipeEdge = */ mSwipeEdge,
+ /* departingAnimationTarget = */ target);
}
/** Creates a progress {@link BackMotionEvent}. */
@@ -237,7 +239,8 @@ public class BackTouchTracker {
/* frameTimeMillis = */ 0,
/* progress = */ progress,
/* triggerBack = */ mTriggerBack,
- /* swipeEdge = */ mSwipeEdge);
+ /* swipeEdge = */ mSwipeEdge,
+ /* departingAnimationTarget = */ null);
}
/** Sets the thresholds for computing progress. */
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index 5b3044e1988a..703274dd708b 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -111,7 +111,7 @@ public enum DesktopModeFlags {
ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
ENABLE_INPUT_LAYER_TRANSITION_FIX(Flags::enableInputLayerTransitionFix, false),
ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
- ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, false),
+ ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, true),
ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS(
Flags::enableOpaqueBackgroundForTransparentWindows, true),
ENABLE_QUICKSWITCH_DESKTOP_SPLIT_BUGFIX(Flags::enableQuickswitchDesktopSplitBugfix, true),
@@ -137,7 +137,7 @@ public enum DesktopModeFlags {
ENABLE_WINDOWING_SCALED_RESIZING(Flags::enableWindowingScaledResizing, true),
ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
Flags::enableWindowingTransitionHandlersObservers, false),
- EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, false),
+ EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, true),
FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK(
Flags::forceCloseTopTransparentFullscreenTask, false),
IGNORE_ASPECT_RATIO_RESTRICTIONS_FOR_RESIZEABLE_FREEFORM_ACTIVITIES(
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 69613a748884..d478108d928a 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -270,7 +270,8 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
mIOnBackInvokedCallback.onBackStarted(
new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(), frameTime,
- backEvent.getProgress(), false, backEvent.getSwipeEdge()));
+ backEvent.getProgress(), false, backEvent.getSwipeEdge(),
+ null));
} catch (RemoteException e) {
Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
}
@@ -285,7 +286,8 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
mIOnBackInvokedCallback.onBackProgressed(
new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(), frameTime,
- backEvent.getProgress(), false, backEvent.getSwipeEdge()));
+ backEvent.getProgress(), false, backEvent.getSwipeEdge(),
+ null));
} catch (RemoteException e) {
Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 36219812c002..7039add0b179 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -88,3 +88,10 @@ flag {
description: "Clear the allowlist duration when clearAllowBgActivityStarts is called"
bug: "322159724"
}
+
+flag {
+ name: "bal_additional_logging"
+ namespace: "responsible_apis"
+ description: "Enable additional logging."
+ bug: "403398176"
+}
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 4261a0f14767..dd9cf9d7718e 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -61,6 +61,8 @@ public class AssistUtils {
public static final int INVOCATION_TYPE_ASSIST_BUTTON = 7;
/** value for INVOCATION_TYPE_KEY: long press on nav handle */
public static final int INVOCATION_TYPE_NAV_HANDLE_LONG_PRESS = 8;
+ /** value for INVOCATION_TYPE_KEY: sysui launcher */
+ public static final int INVOCATION_TYPE_LAUNCHER_SYSTEM_SHORTCUT = 9;
private final Context mContext;
private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index e125e258c596..c25f6b1dcacb 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -322,8 +322,18 @@ public class Cuj {
*/
public static final int CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY = 129;
+ /**
+ * Track the animation of an ongoing call app back into its status bar chip (displaying the call
+ * icon and timer) when returning Home.
+ *
+ * <p>Tracking starts when the RemoteTransition registered to handle the transition from the app
+ * to Home is sent the onAnimationStart() signal and start the animation. Tracking ends when
+ * the animation is fully settled and the transition is complete.</p>
+ */
+ public static final int CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP = 130;
+
// When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
- @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY;
+ @VisibleForTesting static final int LAST_CUJ = CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP;
/** @hide */
@IntDef({
@@ -444,7 +454,8 @@ public class Cuj {
CUJ_LAUNCHER_WORK_UTILITY_VIEW_EXPAND,
CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK,
CUJ_DEFAULT_TASK_TO_TASK_ANIMATION,
- CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY
+ CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY,
+ CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {}
@@ -576,6 +587,7 @@ public class Cuj {
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WORK_UTILITY_VIEW_SHRINK;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DEFAULT_TASK_TO_TASK_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DEFAULT_TASK_TO_TASK_ANIMATION;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_RETURN_TO_CALL_CHIP;
}
private Cuj() {
@@ -830,6 +842,8 @@ public class Cuj {
return "DEFAULT_TASK_TO_TASK_ANIMATION";
case CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY:
return "DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY";
+ case CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP:
+ return "STATUS_BAR_APP_RETURN_TO_CALL_CHIP";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 8151429f9139..f1c47a7a023b 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -760,9 +760,20 @@ public class BatteryStatsHistory {
break;
}
- if (fragment.monotonicTimeMs >= startTimeMs && fragment != mActiveFragment) {
- containers.add(new BatteryHistoryParcelContainer(fragment));
+ if (fragment.monotonicTimeMs >= mHistoryBufferStartTime) {
+ // Do not include the backup of the current buffer, which is explicitly
+ // included later
+ continue;
}
+
+ if (i < fragments.size() - 1
+ && fragments.get(i + 1).monotonicTimeMs < startTimeMs) {
+ // Since fragments are ordered, an early start of next fragment implies an
+ // early end for this one.
+ continue;
+ }
+
+ containers.add(new BatteryHistoryParcelContainer(fragment));
}
}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 33794a59fa21..ac2c51cfe888 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -24,6 +24,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
@@ -290,6 +291,16 @@ public class LatencyTracker {
*/
public static final int ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU = 31;
+ /**
+ * Time it takes for the "exit desktop" mode animation to begin after the user provides input.
+ * <p>
+ * Starts when the user provides input to exit desktop mode and enter full screen mode for an
+ * app. This including selecting the full screen button in an app handle's menu, dragging an
+ * app's window handle to the top of the screen, and using the appropriate keyboard shortcut.
+ * Ends when the animation to exit desktop mode begins.
+ */
+ public static final int ACTION_DESKTOP_MODE_EXIT_MODE = 32;
+
private static final int[] ACTIONS_ALL = {
ACTION_EXPAND_PANEL,
ACTION_TOGGLE_RECENTS,
@@ -323,6 +334,7 @@ public class LatencyTracker {
ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+ ACTION_DESKTOP_MODE_EXIT_MODE,
};
/** @hide */
@@ -359,6 +371,7 @@ public class LatencyTracker {
ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+ ACTION_DESKTOP_MODE_EXIT_MODE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Action {}
@@ -397,6 +410,7 @@ public class LatencyTracker {
UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE,
};
private final Object mLock = new Object();
@@ -601,6 +615,8 @@ public class LatencyTracker {
return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG";
case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU:
return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU";
+ case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE:
+ return "ACTION_DESKTOP_MODE_EXIT_MODE";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/core/java/com/android/internal/widget/NotificationProgressBar.java b/core/java/com/android/internal/widget/NotificationProgressBar.java
index 3472d681a486..f6e2a4df8cca 100644
--- a/core/java/com/android/internal/widget/NotificationProgressBar.java
+++ b/core/java/com/android/internal/widget/NotificationProgressBar.java
@@ -78,6 +78,13 @@ public final class NotificationProgressBar extends ProgressBar implements
@Nullable
private List<DrawablePart> mProgressDrawableParts = null;
+ /** @see R.styleable#NotificationProgressBar_segMinWidth */
+ private final float mSegMinWidth;
+ /** @see R.styleable#NotificationProgressBar_segSegGap */
+ private final float mSegSegGap;
+ /** @see R.styleable#NotificationProgressBar_segPointGap */
+ private final float mSegPointGap;
+
@Nullable
private Drawable mTracker = null;
private boolean mHasTrackerIcon = false;
@@ -128,6 +135,10 @@ public final class NotificationProgressBar extends ProgressBar implements
Log.e(TAG, "Can't get NotificationProgressDrawable", ex);
}
+ mSegMinWidth = a.getDimension(R.styleable.NotificationProgressBar_segMinWidth, 0f);
+ mSegSegGap = a.getDimension(R.styleable.NotificationProgressBar_segSegGap, 0f);
+ mSegPointGap = a.getDimension(R.styleable.NotificationProgressBar_segPointGap, 0f);
+
// Supports setting the tracker in xml, but ProgressStyle notifications set/override it
// via {@code #setProgressTrackerIcon}.
final Drawable tracker = a.getDrawable(R.styleable.NotificationProgressBar_tracker);
@@ -444,30 +455,26 @@ public final class NotificationProgressBar extends ProgressBar implements
return;
}
- final float segSegGap = mNotificationProgressDrawable.getSegSegGap();
- final float segPointGap = mNotificationProgressDrawable.getSegPointGap();
final float pointRadius = mNotificationProgressDrawable.getPointRadius();
mProgressDrawableParts = processPartsAndConvertToDrawableParts(
mParts,
width,
- segSegGap,
- segPointGap,
+ mSegSegGap,
+ mSegPointGap,
pointRadius,
mHasTrackerIcon,
mTrackerDrawWidth
);
- final float segmentMinWidth = mNotificationProgressDrawable.getSegmentMinWidth();
final float progressFraction = getProgressFraction();
final boolean isStyledByProgress = mProgressModel.isStyledByProgress();
- final float progressGap =
- mHasTrackerIcon ? 0F : mNotificationProgressDrawable.getSegSegGap();
+ final float progressGap = mHasTrackerIcon ? 0F : mSegSegGap;
Pair<List<DrawablePart>, Float> p = null;
try {
p = maybeStretchAndRescaleSegments(
mParts,
mProgressDrawableParts,
- segmentMinWidth,
+ mSegMinWidth,
pointRadius,
progressFraction,
isStyledByProgress,
@@ -492,11 +499,11 @@ public final class NotificationProgressBar extends ProgressBar implements
mProgressModel.getProgress(),
getMax(),
width,
- segSegGap,
- segPointGap,
+ mSegSegGap,
+ mSegPointGap,
pointRadius,
mHasTrackerIcon,
- segmentMinWidth,
+ mSegMinWidth,
isStyledByProgress,
mTrackerDrawWidth);
} catch (NotEnoughWidthToFitAllPartsException ex) {
@@ -521,11 +528,11 @@ public final class NotificationProgressBar extends ProgressBar implements
mProgressModel.getProgress(),
getMax(),
width,
- segSegGap,
- segPointGap,
+ mSegSegGap,
+ mSegPointGap,
pointRadius,
mHasTrackerIcon,
- segmentMinWidth,
+ mSegMinWidth,
isStyledByProgress,
mTrackerDrawWidth);
} catch (NotEnoughWidthToFitAllPartsException ex) {
diff --git a/core/java/com/android/internal/widget/NotificationProgressDrawable.java b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
index b1096107f04b..32b283af29c5 100644
--- a/core/java/com/android/internal/widget/NotificationProgressDrawable.java
+++ b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
@@ -84,27 +84,6 @@ public final class NotificationProgressDrawable extends Drawable {
}
/**
- * Returns the gap between two segments.
- */
- public float getSegSegGap() {
- return mState.mSegSegGap;
- }
-
- /**
- * Returns the gap between a segment and a point.
- */
- public float getSegPointGap() {
- return mState.mSegPointGap;
- }
-
- /**
- * Returns the gap between a segment and a point.
- */
- public float getSegmentMinWidth() {
- return mState.mSegmentMinWidth;
- }
-
- /**
* Returns the radius for the points.
*/
public float getPointRadius() {
@@ -241,11 +220,6 @@ public final class NotificationProgressDrawable extends Drawable {
mState.setDensity(resolveDensity(r, 0));
- final TypedArray a = obtainAttributes(r, theme, attrs,
- R.styleable.NotificationProgressDrawable);
- updateStateFromTypedArray(a);
- a.recycle();
-
inflateChildElements(r, parser, attrs, theme);
updateLocalState();
@@ -262,13 +236,6 @@ public final class NotificationProgressDrawable extends Drawable {
state.setDensity(resolveDensity(t.getResources(), 0));
- if (state.mThemeAttrs != null) {
- final TypedArray a = t.resolveAttributes(
- state.mThemeAttrs, R.styleable.NotificationProgressDrawable);
- updateStateFromTypedArray(a);
- a.recycle();
- }
-
applyThemeChildElements(t);
updateLocalState();
@@ -279,21 +246,6 @@ public final class NotificationProgressDrawable extends Drawable {
return (mState.canApplyTheme()) || super.canApplyTheme();
}
- private void updateStateFromTypedArray(TypedArray a) {
- final State state = mState;
-
- // Account for any configuration changes.
- state.mChangingConfigurations |= a.getChangingConfigurations();
-
- // Extract the theme attributes, if any.
- state.mThemeAttrs = a.extractThemeAttrs();
-
- state.mSegSegGap = a.getDimension(R.styleable.NotificationProgressDrawable_segSegGap,
- state.mSegSegGap);
- state.mSegPointGap = a.getDimension(R.styleable.NotificationProgressDrawable_segPointGap,
- state.mSegPointGap);
- }
-
private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
Theme theme) throws XmlPullParserException, IOException {
TypedArray a;
@@ -357,8 +309,6 @@ public final class NotificationProgressDrawable extends Drawable {
// Extract the theme attributes, if any.
state.mThemeAttrsSegments = a.extractThemeAttrs();
- state.mSegmentMinWidth = a.getDimension(
- R.styleable.NotificationProgressDrawableSegments_minWidth, state.mSegmentMinWidth);
state.mSegmentHeight = a.getDimension(
R.styleable.NotificationProgressDrawableSegments_height, state.mSegmentHeight);
state.mFadedSegmentHeight = a.getDimension(
@@ -588,9 +538,6 @@ public final class NotificationProgressDrawable extends Drawable {
static final class State extends ConstantState {
@Config
int mChangingConfigurations;
- float mSegSegGap = 0.0f;
- float mSegPointGap = 0.0f;
- float mSegmentMinWidth = 0.0f;
float mSegmentHeight;
float mFadedSegmentHeight;
float mSegmentCornerRadius;
@@ -610,9 +557,6 @@ public final class NotificationProgressDrawable extends Drawable {
State(@NonNull State orig, @Nullable Resources res) {
mChangingConfigurations = orig.mChangingConfigurations;
- mSegSegGap = orig.mSegSegGap;
- mSegPointGap = orig.mSegPointGap;
- mSegmentMinWidth = orig.mSegmentMinWidth;
mSegmentHeight = orig.mSegmentHeight;
mFadedSegmentHeight = orig.mFadedSegmentHeight;
mSegmentCornerRadius = orig.mSegmentCornerRadius;
@@ -631,18 +575,6 @@ public final class NotificationProgressDrawable extends Drawable {
}
private void applyDensityScaling(int sourceDensity, int targetDensity) {
- if (mSegSegGap > 0) {
- mSegSegGap = scaleFromDensity(
- mSegSegGap, sourceDensity, targetDensity);
- }
- if (mSegPointGap > 0) {
- mSegPointGap = scaleFromDensity(
- mSegPointGap, sourceDensity, targetDensity);
- }
- if (mSegmentMinWidth > 0) {
- mSegmentMinWidth = scaleFromDensity(
- mSegmentMinWidth, sourceDensity, targetDensity);
- }
if (mSegmentHeight > 0) {
mSegmentHeight = scaleFromDensity(
mSegmentHeight, sourceDensity, targetDensity);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 766fbf1a80f5..d62538b6d1ed 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -73,7 +73,7 @@ public class CoreDocument implements Serializable {
// We also keep a more fine-grained BUILD number, exposed as
// ID_API_LEVEL = DOCUMENT_API_LEVEL + BUILD
- static final float BUILD = 0.7f;
+ static final float BUILD = 0.8f;
private static final boolean UPDATE_VARIABLES_BEFORE_LAYOUT = false;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index add9d5bae552..20252366e264 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -30,6 +30,7 @@ import com.android.internal.widget.remotecompose.core.operations.DataListFloat;
import com.android.internal.widget.remotecompose.core.operations.DataListIds;
import com.android.internal.widget.remotecompose.core.operations.DataMapIds;
import com.android.internal.widget.remotecompose.core.operations.DataMapLookup;
+import com.android.internal.widget.remotecompose.core.operations.DebugMessage;
import com.android.internal.widget.remotecompose.core.operations.DrawArc;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmapFontText;
@@ -231,6 +232,7 @@ public class Operations {
public static final int PATH_COMBINE = 175;
public static final int HAPTIC_FEEDBACK = 177;
public static final int CONDITIONAL_OPERATIONS = 178;
+ public static final int DEBUG_MESSAGE = 179;
///////////////////////////////////////// ======================
@@ -443,6 +445,7 @@ public class Operations {
map.put(PATH_COMBINE, PathCombine::read);
map.put(HAPTIC_FEEDBACK, HapticFeedback::read);
map.put(CONDITIONAL_OPERATIONS, ConditionalOperations::read);
+ map.put(DEBUG_MESSAGE, DebugMessage::read);
// map.put(ACCESSIBILITY_CUSTOM_ACTION, CoreSemantics::read);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 1f026687680f..eb7399afd2b7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -33,6 +33,7 @@ import com.android.internal.widget.remotecompose.core.operations.DataListFloat;
import com.android.internal.widget.remotecompose.core.operations.DataListIds;
import com.android.internal.widget.remotecompose.core.operations.DataMapIds;
import com.android.internal.widget.remotecompose.core.operations.DataMapLookup;
+import com.android.internal.widget.remotecompose.core.operations.DebugMessage;
import com.android.internal.widget.remotecompose.core.operations.DrawArc;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
import com.android.internal.widget.remotecompose.core.operations.DrawBitmapFontText;
@@ -1870,6 +1871,46 @@ public class RemoteComposeBuffer {
}
/**
+ * Add a scroll modifier
+ *
+ * @param direction HORIZONTAL(0) or VERTICAL(1)
+ * @param positionId the position id as a NaN
+ */
+ public void addModifierScroll(int direction, float positionId) {
+ float max = this.reserveFloatVariable();
+ float notchMax = this.reserveFloatVariable();
+ float touchExpressionDirection =
+ direction != 0 ? RemoteContext.FLOAT_TOUCH_POS_X : RemoteContext.FLOAT_TOUCH_POS_Y;
+
+ ScrollModifierOperation.apply(mBuffer, direction, positionId, max, notchMax);
+ this.addTouchExpression(
+ positionId,
+ 0f,
+ 0f,
+ max,
+ 0f,
+ 3,
+ new float[] {
+ touchExpressionDirection, -1, MUL,
+ },
+ TouchExpression.STOP_GENTLY,
+ null,
+ null);
+ ContainerEnd.apply(mBuffer);
+ }
+
+ /**
+ * Add a scroll modifier
+ *
+ * @param direction HORIZONTAL(0) or VERTICAL(1)
+ */
+ public void addModifierScroll(int direction) {
+ float max = this.reserveFloatVariable();
+ ScrollModifierOperation.apply(mBuffer, direction, 0f, max, 0f);
+ ContainerEnd.apply(mBuffer);
+ }
+
+ /**
* Add a background modifier of provided color
*
* @param color the color of the background
@@ -2464,4 +2505,15 @@ public class RemoteComposeBuffer {
public void addConditionalOperations(byte type, float a, float b) {
ConditionalOperations.apply(mBuffer, type, a, b);
}
+
+ /**
+ * Add a debug message
+ *
+ * @param textId text id
+ * @param value value
+ * @param flags flags
+ */
+ public void addDebugMessage(int textId, float value, int flags) {
+ DebugMessage.apply(mBuffer, textId, value, flags);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java
new file mode 100644
index 000000000000..c27bd8b577bf
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java
@@ -0,0 +1,157 @@
+/*
+ * 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.internal.widget.remotecompose.core.operations;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+
+import java.util.List;
+
+/**
+ * This prints debugging message useful for debugging. It should not be use in production documents
+ */
+public class DebugMessage extends Operation implements VariableSupport {
+ private static final int OP_CODE = Operations.DEBUG_MESSAGE;
+ private static final String CLASS_NAME = "DebugMessage";
+ int mTextID;
+ float mFloatValue;
+ float mOutFloatValue;
+ int mFlags = 0;
+
+ public DebugMessage(int textID, float value, int flags) {
+ mTextID = textID;
+ mFloatValue = value;
+ mFlags = flags;
+ }
+
+ @Override
+ public void updateVariables(@NonNull RemoteContext context) {
+ System.out.println("Debug message : updateVariables ");
+ mOutFloatValue =
+ Float.isNaN(mFloatValue)
+ ? context.getFloat(Utils.idFromNan(mFloatValue))
+ : mFloatValue;
+ System.out.println(
+ "Debug message : updateVariables "
+ + Utils.floatToString(mFloatValue, mOutFloatValue));
+ }
+
+ @Override
+ public void registerListening(@NonNull RemoteContext context) {
+ System.out.println("Debug message : registerListening ");
+
+ if (Float.isNaN(mFloatValue)) {
+ System.out.println("Debug message : registerListening " + mFloatValue);
+ context.listensTo(Utils.idFromNan(mFloatValue), this);
+ }
+ }
+
+ @Override
+ public void write(@NonNull WireBuffer buffer) {
+ apply(buffer, mTextID, mFloatValue, mFlags);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "DebugMessage "
+ + mTextID
+ + ", "
+ + Utils.floatToString(mFloatValue, mOutFloatValue)
+ + ", "
+ + mFlags;
+ }
+
+ /**
+ * Read this operation and add it to the list of operations
+ *
+ * @param buffer the buffer to read
+ * @param operations the list of operations that will be added to
+ */
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ int text = buffer.readInt();
+ float floatValue = buffer.readFloat();
+ int flags = buffer.readInt();
+ DebugMessage op = new DebugMessage(text, floatValue, flags);
+ operations.add(op);
+ }
+
+ /**
+ * The name of the class
+ *
+ * @return the name
+ */
+ @NonNull
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ /**
+ * The OP_CODE for this command
+ *
+ * @return the opcode
+ */
+ public static int id() {
+ return OP_CODE;
+ }
+
+ /**
+ * Writes out the operation to the buffer
+ *
+ * @param buffer write the command to the buffer
+ * @param textID id of the text
+ * @param value value to print
+ * @param flags flags to print
+ */
+ public static void apply(@NonNull WireBuffer buffer, int textID, float value, int flags) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(textID);
+ buffer.writeFloat(value);
+ buffer.writeInt(flags);
+ }
+
+ /**
+ * Populate the documentation with a description of this operation
+ *
+ * @param doc to append the description to.
+ */
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("DebugMessage Operations", id(), CLASS_NAME)
+ .description("Print debugging messages")
+ .field(DocumentedOperation.INT, "textId", "test to print")
+ .field(DocumentedOperation.FLOAT, "value", "value of a float to print")
+ .field(DocumentedOperation.INT, "flags", "print additional information");
+ }
+
+ @Override
+ public void apply(@NonNull RemoteContext context) {
+ String str = context.getText(mTextID);
+ System.out.println("Debug message : " + str + " " + mOutFloatValue + " " + mFlags);
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return indent + toString();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
index dee79a45de3d..67d3a6584897 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
@@ -266,10 +266,12 @@ public class TimeAttribute extends PaintOperation {
case TIME_FROM_NOW_SEC:
case TIME_FROM_ARG_SEC:
ctx.loadFloat(mId, (delta) * 1E-3f);
+ ctx.needsRepaint();
break;
case TIME_FROM_ARG_MIN:
case TIME_FROM_NOW_MIN:
ctx.loadFloat(mId, (float) (delta * 1E-3 / 60));
+ ctx.needsRepaint();
break;
case TIME_FROM_ARG_HR:
case TIME_FROM_NOW_HR:
@@ -298,6 +300,7 @@ public class TimeAttribute extends PaintOperation {
break;
case TIME_FROM_LOAD_SEC:
ctx.loadFloat(mId, (value - load_time) * 1E-3f);
+ ctx.needsRepaint();
break;
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
index f24672922367..3e5dff8ad277 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -494,7 +494,7 @@ public class TouchExpression extends Operation
mTouchUpTime = context.getAnimationTime();
float dest = getStopPosition(value, slope);
- float time = mMaxTime * Math.abs(dest - value) / (2 * mMaxVelocity);
+ float time = Math.min(2, mMaxTime * Math.abs(dest - value) / (2 * mMaxVelocity));
mEasyTouch.config(value, dest, slope, time, mMaxAcceleration, mMaxVelocity, null);
mEasingToStop = true;
context.needsRepaint();
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 17f4fc82af5f..e76fb0654df6 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -42,6 +42,9 @@ import java.util.Set;
public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachStateChangeListener {
static final boolean USE_VIEW_AREA_CLICK = true; // Use views to represent click areas
+ static final float DEFAULT_FRAME_RATE = 60f;
+ static final float POST_TO_NEXT_FRAME_THRESHOLD = 60f;
+
RemoteComposeDocument mDocument = null;
int mTheme = Theme.LIGHT;
boolean mInActionDown = false;
@@ -53,9 +56,11 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
long mStart = System.nanoTime();
long mLastFrameDelay = 1;
- float mMaxFrameRate = 60f; // frames per seconds
+ float mMaxFrameRate = DEFAULT_FRAME_RATE; // frames per seconds
long mMaxFrameDelay = (long) (1000 / mMaxFrameRate);
+ long mLastFrameCall = System.currentTimeMillis();
+
private Choreographer mChoreographer;
private Choreographer.FrameCallback mFrameCallback =
new Choreographer.FrameCallback() {
@@ -100,6 +105,7 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
public void setDocument(RemoteComposeDocument value) {
mDocument = value;
+ mMaxFrameRate = DEFAULT_FRAME_RATE;
mDocument.initializeContext(mARContext);
mDisable = false;
mARContext.setDocLoadTime();
@@ -546,8 +552,25 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
}
int nextFrame = mDocument.needsRepaint();
if (nextFrame > 0) {
- mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
+ if (mMaxFrameRate >= POST_TO_NEXT_FRAME_THRESHOLD) {
+ mLastFrameDelay = nextFrame;
+ } else {
+ mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
+ }
if (mChoreographer != null) {
+ if (mDebug == 1) {
+ System.err.println(
+ "RC : POST CHOREOGRAPHER WITH "
+ + mLastFrameDelay
+ + " (nextFrame was "
+ + nextFrame
+ + ", max delay "
+ + mMaxFrameDelay
+ + ", "
+ + " max framerate is "
+ + mMaxFrameRate
+ + ")");
+ }
mChoreographer.postFrameCallbackDelayed(mFrameCallback, mLastFrameDelay);
}
if (!mARContext.useChoreographer()) {
@@ -567,6 +590,16 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
mDisable = true;
invalidate();
}
+ if (mDebug == 1) {
+ long frameDelay = System.currentTimeMillis() - mLastFrameCall;
+ System.err.println(
+ "RC : Delay since last frame "
+ + frameDelay
+ + " ms ("
+ + (1000f / (float) frameDelay)
+ + " fps)");
+ mLastFrameCall = System.currentTimeMillis();
+ }
}
private void drawDisable(Canvas canvas) {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index a0c8f30c9356..36bda61c94a6 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -73,6 +73,7 @@ static struct bindernative_offsets_t
jmethodID mExecTransact;
jmethodID mGetInterfaceDescriptor;
jmethodID mTransactionCallback;
+ jmethodID mGetExtension;
// Object state.
jfieldID mObject;
@@ -488,8 +489,12 @@ public:
if (mVintf) {
::android::internal::Stability::markVintf(b.get());
}
- if (mExtension != nullptr) {
- b.get()->setExtension(mExtension);
+ if (mSetExtensionCalled) {
+ jobject javaIBinderObject = env->CallObjectMethod(obj, gBinderOffsets.mGetExtension);
+ sp<IBinder> extensionFromJava = ibinderForJavaObject(env, javaIBinderObject);
+ if (extensionFromJava != nullptr) {
+ b.get()->setExtension(extensionFromJava);
+ }
}
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
@@ -515,21 +520,12 @@ public:
mVintf = false;
}
- sp<IBinder> getExtension() {
- AutoMutex _l(mLock);
- sp<JavaBBinder> b = mBinder.promote();
- if (b != nullptr) {
- return b.get()->getExtension();
- }
- return mExtension;
- }
-
void setExtension(const sp<IBinder>& extension) {
AutoMutex _l(mLock);
- mExtension = extension;
+ mSetExtensionCalled = true;
sp<JavaBBinder> b = mBinder.promote();
if (b != nullptr) {
- b.get()->setExtension(mExtension);
+ b.get()->setExtension(extension);
}
}
@@ -541,8 +537,7 @@ private:
// is too much binder state here, we can think about making JavaBBinder an
// sp here (avoid recreating it)
bool mVintf = false;
-
- sp<IBinder> mExtension;
+ bool mSetExtensionCalled = false;
};
// ----------------------------------------------------------------------------
@@ -1254,10 +1249,6 @@ static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject cla
return IPCThreadState::self()->blockUntilThreadAvailable();
}
-static jobject android_os_Binder_getExtension(JNIEnv* env, jobject obj) {
- JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
- return javaObjectForIBinder(env, jbh->getExtension());
-}
static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
@@ -1300,8 +1291,7 @@ static const JNINativeMethod gBinderMethods[] = {
{ "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
{ "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
- { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
- { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
+ { "setExtensionNative", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
};
// clang-format on
@@ -1318,6 +1308,8 @@ static int int_register_android_os_Binder(JNIEnv* env)
gBinderOffsets.mTransactionCallback =
GetStaticMethodIDOrDie(env, clazz, "transactionCallback", "(IIII)V");
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
+ gBinderOffsets.mGetExtension = GetMethodIDOrDie(env, clazz, "getExtension",
+ "()Landroid/os/IBinder;");
return RegisterMethodsOrDie(
env, kBinderPathName,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e16ce9849ff2..9e0200481421 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5394,13 +5394,13 @@
corresponding permission such as {@link #HEAD_TRACKING} or
{@link #FACE_TRACKING} for the data being accessed.
- <p>Protection level: normal|appop
+ <p>Protection level: signature|privileged
@SystemApi
@FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
@hide -->
<permission android:name="android.permission.XR_TRACKING_IN_BACKGROUND"
- android:protectionLevel="normal|appop"
+ android:protectionLevel="signature|privileged"
android:description="@string/permdesc_xr_tracking_in_background"
android:label="@string/permlab_xr_tracking_in_background"
android:featureFlag="android.xr.xr_manifest_entries" />
diff --git a/core/res/res/drawable/notification_progress.xml b/core/res/res/drawable/notification_progress.xml
index ff5450ee106f..92a0a6a4e21b 100644
--- a/core/res/res/drawable/notification_progress.xml
+++ b/core/res/res/drawable/notification_progress.xml
@@ -19,12 +19,9 @@
android:gravity="center_vertical|fill_horizontal">
<com.android.internal.widget.NotificationProgressDrawable
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:segSegGap="@dimen/notification_progress_segSeg_gap"
- android:segPointGap="@dimen/notification_progress_segPoint_gap">
+ android:layout_height="wrap_content">
<segments
android:color="?attr/colorProgressBackgroundNormal"
- android:minWidth="@dimen/notification_progress_segments_min_width"
android:height="@dimen/notification_progress_segments_height"
android:fadedHeight="@dimen/notification_progress_segments_faded_height"
android:cornerRadius="@dimen/notification_progress_segments_corner_radius"/>
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 57c89b91cff7..201f46025286 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -74,6 +74,7 @@
android:id="@+id/notification_headerless_view_column"
android:layout_width="0px"
android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
android:layout_weight="1"
android:layout_marginVertical="@dimen/notification_2025_reduced_margin"
android:orientation="vertical"
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 de82f9feb512..e599de12097a 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_media.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -76,6 +76,7 @@
android:id="@+id/notification_headerless_view_column"
android:layout_width="0px"
android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
android:layout_weight="1"
android:layout_marginVertical="@dimen/notification_2025_reduced_margin"
android:orientation="vertical"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 568468b51f47..1cab0dc1b851 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rollees"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Onderbreek"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisie"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rollees op"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rollees af"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rollees na links"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rollees na regs"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Gaan uit Rolleesmodus"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rolleespaneel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"het \'n prent gestuur"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Werk 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Toets"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Gemeenskaplik"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Toesighoudend"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Werkprofiel"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privaat ruimte"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 20d5336959d2..bda4da077204 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ሸብልል"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ባለበት አቁም"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"አቀማመጥ"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ወደ ላይ ሸብልል"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ወደ ታች ሸብልል"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ወደ ግራ ሸብልል"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ወደ ቀኝ ሸብልል"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ከሸብልል ሁነታ ውጣ"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"የመሸብለል ፓነል"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ወደ የRESTRICTED ባልዲ ተከትቷል"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>፦"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"አንድ ምስል ልከዋል"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ሥራ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ሙከራ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"የጋራ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ክትትል በማድረግ ላይ"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"የሥራ መገለጫ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"የግል ቦታ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"አባዛ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index ffc144416d91..7daa4b49786d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -2490,8 +2490,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ملف العمل 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ملف شخصي تجريبي"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"ملف شخصي مشترك"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"المُشرف"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ملف العمل"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"المساحة الخاصة"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"نسخة طبق الأصل"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5c78cded7df6..5f7ef0078a0f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্ৰ’ল কৰক"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ কৰক"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"স্থান"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ওপৰলৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"তললৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"বাওঁফাললৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"সোঁফাললৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"স্ক্ৰ’ল ম’ডৰ পৰা বাহিৰ হওক"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"স্ক্ৰ’ল পেনেল"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"কৰ্মস্থান ৩"</string>
<string name="profile_label_test" msgid="9168641926186071947">"পৰীক্ষা"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"শ্বেয়াৰ কৰা"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"তদাৰক কৰি থকা হৈছে"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"কৰ্মস্থানৰ প্ৰ’ফাইল"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"প্ৰাইভেট স্পে’চ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ক্ল’ন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c8b500be22c6..bc8a3f337f10 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"İş 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Kommunal"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nəzarət edilir"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"İş profili"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Məxfi sahə"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index d1889b84e90f..8b742006075f 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Skrolujte"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Skroluj nagore"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Skroluj nadole"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Skroluj ulevo"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Skroluj udesno"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izađi iz režima skrolovanja"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Okno za skrolovanje"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Posao 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzire se"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Poslovni profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatan prostor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klonirano"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 68fe703644a9..cbdbc23e0028 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Гартанне"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Прыпыніць"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Пазіцыя"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прагартаць уверх"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прагартаць уніз"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прагартаць улева"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прагартаць управа"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Выйсці з рэжыму гартання"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панэль прагортвання"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" дададзены ў АБМЕЖАВАНУЮ групу"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"адпраўлены відарыс"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Працоўны 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Тэставы"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Супольны"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Бацькоўскі кантроль"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Працоўны профіль"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Прыватная прастора"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 67e711f115df..a1140b930ec1 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Служебни 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Тестване"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Общи"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Контролиране"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Служебен потребителски профил"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Частно пространство"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клониране"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 12bf5dab6561..426c711adbf1 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্রল করুন"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ করুন"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"পজিশন"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"উপর দিকে স্ক্রল করুন"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"নিচে স্ক্রল করুন"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"বাঁদিকে স্ক্রল করুন"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ডানদিকে স্ক্রল করুন"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"স্ক্রল মোড থেকে বেরিয়ে আসুন"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"স্ক্রল প্যানেল"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"একটি ছবি পাঠানো হয়েছে"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"৩য় অফিস"</string>
<string name="profile_label_test" msgid="9168641926186071947">"পরীক্ষা"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"কমিউনাল"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"তত্ত্বাবধান করা"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"অফিস প্রোফাইল"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"প্রাইভেট স্পেস"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ক্লোন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 441d51461f08..947f6bacafc7 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Klizanje"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Položaj"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Klizanje nagore"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Klizanje nadolje"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Klizanje ulijevo"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Klizanje udesno"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izlaz iz načina rada za klizanje"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ploča za klizanje"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"3. poslovno"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Testno"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Opće"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzor"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Radni profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatni prostor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index efde1506e7be..8dcf67195842 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplaça"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Posa en pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posició"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplaça\'t cap amunt"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplaça\'t cap avall"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplaça\'t cap a l\'esquerra"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplaça\'t cap a la dreta"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Surt del mode de desplaçament"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Tauler de desplaçament"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> s\'ha transferit al segment RESTRINGIT"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha enviat una imatge"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Treball 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Prova"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Compartit"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"En supervisió"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de treball"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espai privat"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 59de93743290..61d9249e7774 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Posunutí"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pozastavit"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozice"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Posunout nahoru"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Posunout dolů"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Posunout doleva"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Posunout doprava"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ukončit režim posouvání"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel posouvání"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"posílá obrázek"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Práce 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Komunální"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Dohled"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Pracovní profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Soukromý prostor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 1038ff0bcf8f..8d8918fbf16e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rul"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sæt på pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Placering"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rul op"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rul ned"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rul til venstre"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rul til højre"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Afslut rulletilstand"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rullepanel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blevet placeret i samlingen BEGRÆNSET"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sendte et billede"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Arbejde 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Fælles"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Forældrestyring"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Arbejdsprofil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat område"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index c13dacad4dea..15edddee0dbe 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrollen"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausieren"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Nach oben scrollen"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Nach unten scrollen"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Nach links scrollen"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Nach rechts scrollen"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Scrollmodus beenden"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Bildlaufleiste"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> wurde in den BESCHRÄNKT-Bucket gelegt"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"hat ein Bild gesendet"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Geschäftlich 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Gemeinsam genutzt"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Elternaufsicht"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Arbeitsprofil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Vertrauliches Profil"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 50b06dfbc8b6..5d83f7890d6b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Κύλιση"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Παύση"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Θέση"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Κύλιση προς τα επάνω"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Κύλιση προς τα κάτω"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Κύλιση προς τα αριστερά"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Κύλιση προς τα δεξιά"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Έξοδος από τη λειτουργία κύλισης"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Πλαίσιο κύλισης"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Το πακέτο <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"έστειλε μια εικόνα"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Εργασία 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Δοκιμή"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Κοινόχρηστο"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Επίβλεψη"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Προφίλ εργασίας"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ιδιωτικός χώρος"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Κλώνος"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 74462e996b5b..532fee688acd 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9fa268338d4a..c079a4804057 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e162a6094719..62daeffa9043 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 330039740ea1..b5a5e8f0deeb 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazarse"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplazarse hacia arriba"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplazarse hacia abajo"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplazarse a la izquierda"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplazarse a la derecha"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Salir del modo de desplazamiento"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desplazamiento"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> se ha incluido en el grupo de restringidos"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha enviado una imagen"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Trabajo 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Prueba"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Común"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisando"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabajo"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espacio privado"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c172de8671c9..99f9791e6ff1 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Keri"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Peata"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Asukoht"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Keri üles"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Keri alla"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Keri vasakule"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Keri paremale"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Välju kerimisrežiimist"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Keri paneelil"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on lisatud salve PIIRANGUTEGA"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"saatis kujutise"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Töö 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Jagatud"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Järelevalve"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Tööprofiil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privaatne ruum"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 24dbe4bb580c..7a49905cb250 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -2492,8 +2492,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Lanekoa 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Probakoa"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Partekatua"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Gainbegiratzea"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Laneko profila"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Eremu pribatua"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klona"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index f31bb1044c96..820a80c1f411 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"کار ۳"</string>
<string name="profile_label_test" msgid="9168641926186071947">"آزمایش"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"عمومی"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"نظارت"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"نمایه کاری"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"فضای خصوصی"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"همسانه‌سازی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f1a5fbcdbcc4..dce063d0b033 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Vieritä"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Keskeytä"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Sijainti"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Vieritys ylös"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Vieritä alas"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Vieritä vasemmalle"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Vieritä oikealle"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Poistu vieritystilasta"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Vierityspaneeli"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on nyt rajoitettujen ryhmässä"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"lähetti kuvan"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Työ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Testi"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Jaettu"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Valvotaan"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Työprofiili"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Yksityinen tila"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klooni"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index a7b12891d7b1..127e6fcc97f7 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -2487,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Professionnel 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervision"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil professionnel"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espace privé"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 213c25696ec0..a30c414038af 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Faire défiler vers le haut"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Faire défiler vers le bas"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Faire défiler vers la gauche"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Faire défiler vers la droite"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Quitter le mode défilement"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panneau de défilement"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le bucket RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a envoyé une image"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Professionnel 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervision"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil professionnel"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espace privé"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8c265b02b93e..d79e3c63e084 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desprazar"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desprazarse cara arriba"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desprazarse cara abaixo"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desprazar cara á esquerda"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desprazar cara á dereita"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Saír do modo de desprazamento"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desprazamento"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviouse unha imaxe"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Traballo 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Proba"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisión"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de traballo"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espazo privado"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clonado"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index c4da34989482..6b1e2840522a 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1803,8 +1803,7 @@
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"એક-હાથે વાપરો મોડ"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"એક્સ્ટ્રા ડિમ"</string>
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"સાંભળવામાં સહાય કરતા ડિવાઇસ"</string>
- <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
- <skip />
+ <string name="autoclick_feature_name" msgid="8149248738736949630">"ઑટોક્લિક"</string>
<string name="hearing_device_status_disconnected" msgid="497547752953543832">"ડિસ્કનેક્ટેડ છે"</string>
<string name="hearing_device_status_connected" msgid="2149385149669918764">"કનેક્ટેડ છે"</string>
<string name="hearing_device_status_active" msgid="4770378695482566032">"સક્રિય"</string>
@@ -2274,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"સ્ક્રોલ કરો"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"થોભાવો"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"સ્થિતિ"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ઉપર સ્ક્રોલ કરો"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"નીચે સ્ક્રોલ કરો"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ડાબે સ્ક્રોલ કરો"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"જમણે સ્ક્રોલ કરો"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"સ્ક્રોલ મોડમાંથી બહાર નીકળો"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"સ્ક્રોલ પૅનલ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ને પ્રતિબંધિત સમૂહમાં મૂકવામાં આવ્યું છે"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"છબી મોકલી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 01e5c7786cb7..b8be4057d480 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल करें"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"रोकें"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"पोज़िशन"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ऊपर की ओर स्क्रोल करें"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"नीचे की ओर स्क्रोल करें"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"बाईं ओर स्क्रोल करें"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"दाईं ओर स्क्रोल करें"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल मोड को बंद करें"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"पैनल को स्क्रोल करें"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> को प्रतिबंधित बकेट में रखा गया है"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"एक इमेज भेजी गई"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ऑफ़िस 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"टेस्ट"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"कम्यूनिटी"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"निगरानी की जा रही है"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"वर्क प्रोफ़ाइल"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"प्राइवेट स्पेस"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"क्लोन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 826b860dfc2b..77c9a6049f0d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Pomakni se"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Pomakni prema gore"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pomakni prema dolje"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Pomakni ulijevo"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Pomakni udesno"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izađi iz načina pomicanja"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ploča za pomicanje"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> premješten je u spremnik OGRANIČENO"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"šalje sliku"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Posao 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzire se"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Radni profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatni prostor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1519326cdb6b..24babe3305e5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Görgetés"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Szüneteltetés"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozíció"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Görgetés felfelé"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Görgetés lefelé"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Görgetés balra"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Görgetés jobbra"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Kilépés a görgetési módból"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Görgetési panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"képet küldött"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"3. munkahelyi"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Teszt"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Közös"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Aktív felügyelet"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Munkaprofil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privát terület"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klón"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 2fd68c11ba7b..7f78454e950c 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Աշխատանքային 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Փորձնական"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Ընդհանուր"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Վերահսկում"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Աշխատանքային պրոֆիլ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Մասնավոր տարածք"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Կլոն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 6e686b4263dd..fbbf2855565d 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Jeda"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisi"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll ke Atas"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll ke Bawah"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll ke Kiri"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll ke Kanan"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Keluar dari Mode Scroll"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel Scroll"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah dimasukkan ke dalam bucket DIBATASI"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"mengirim gambar"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Kerja 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Pengujian"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Mengawasi"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil kerja"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ruang privasi"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 35b102e42933..d148f5d6de08 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Fletta"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Hlé"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Staðsetning"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Fletta upp"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Fletta niður"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Fletta til vinstri"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Fletta til hægri"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Loka flettistillingu"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Flettisvæði"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> var sett í flokkinn TAKMARKAÐ"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sendi mynd"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 28aee0fbba0c..7fe1bdc6762d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scorri"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Metti in pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posizione"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scorri verso l\'alto"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scorri verso il basso"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scorri verso sinistra"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scorri verso destra"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Disattiva la modalità di scorrimento"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Riquadro di scorrimento"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> è stato inserito nel bucket RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha inviato un\'immagine"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5eadbd413f2c..c32bcdda3692 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"גלילה"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"השהיה"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"מיקום"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"גלילה למעלה"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"גלילה למטה"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"גלילה שמאלה"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"גלילה ימינה"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"יציאה ממצב גלילה"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"גלילה בחלונית"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> התווספה לקטגוריה \'מוגבל\'"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"נשלחה תמונה"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"פרופיל עבודה 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"בדיקה"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"שיתופי"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"פרופיל מפקח"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"פרופיל העבודה"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"המרחב הפרטי"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"שכפול"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 24e45df6d1ac..97e550d9e4db 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Айналдыру"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Кідірту"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орналастыру"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Жоғары айналдыру"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Төменге айналдыру"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Солға айналдыру"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Оңға айналдыру"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Айналдыру режимінен шығу"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Айналдыру панелі"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ШЕКТЕЛГЕН себетке салынды."</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"сурет жіберілді"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Жұмыс 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Сынақ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Қадағалау"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Жұмыс профилі"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Құпия кеңістік"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c9a0f211a4e8..316955f0717b 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ಕೆಲಸ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ಪರೀಕ್ಷೆ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"ಸಮುದಾಯ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ಮೇಲ್ವಿಚಾರಣೆಯಾಗುತ್ತಿದೆ"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"ಪ್ರೈವೆಟ್ ಸ್ಪೇಸ್"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ಕ್ಲೋನ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 852051f0d8e2..bd48cb3e3bf8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"스크롤"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"일시중지"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"위치"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"위로 스크롤"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"아래로 스크롤"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"왼쪽으로 스크롤"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"오른쪽으로 스크롤"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"스크롤 모드 종료"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"패널 스크롤"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 항목이 RESTRICTED 버킷으로 이동함"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"이미지 보냄"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"직장 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"테스트"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"공동"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"감독 중"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"직장 프로필"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"비공개 스페이스"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"클론"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 8115a000a42a..906d4a3ed0fa 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Сыдыруу"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Тындыруу"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орду"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Жогору сыдыруу"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Ылдый сыдыруу"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Солго сыдырып кароо"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Оңго сыдырып кароо"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Сыдыруу режиминен чыгуу"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Сыдыруу панели"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ЧЕКТЕЛГЕН чакага коюлган"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"сүрөт жөнөттү"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Жумуш 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Сыноо"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Көзөмөлдөнүүдө"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Жумуш профили"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Жеке мейкиндик"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index b9868d1f82f6..e6222da7af40 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ວຽກ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ທົດສອບ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"ສ່ວນກາງ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ການເບິ່ງແຍງກວດກາ"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"ພື້ນທີ່ສ່ວນບຸກຄົນ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ໂຄລນ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c71c2b8e612e..3a2836833ea4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -2488,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Darbas (3)"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Bandymas"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Bendruomenės"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Prižiūrima"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Darbo profilis"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privati erdvė"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klonuoti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 252343724908..b0f6313c214d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ritināt"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pārtraukt"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozīcija"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Ritināt augšup"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Ritināt lejup"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Ritināt pa kreisi"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Ritināt pa labi"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izslēgt ritināšanas režīmu"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ritināšanas panelis"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"nosūtīts attēls"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Darbam (3.)"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Testēšanai"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Kopīgs"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Uzraudzība"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Darba profils"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privātā telpa"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klons"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index c6cb1faa850b..8b389a0e5a1b 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Лизгање"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Паузирај"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиционирај"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Лизгај нагоре"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Лизгај надолу"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Лизгај налево"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Лизгај надесно"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Излези од „Режим на лизгање“"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Табла за лизгање"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е ставен во корпата ОГРАНИЧЕНИ"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"испрати слика"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Работен профил 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Профил на заедницата"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Вршење надзор"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Работен профил"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватен простор"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клониран профил"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index fca58a113c7b..825da1894522 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"സ്‌ക്രോൾ ചെയ്യുക"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"താൽക്കാലികമായി നിർത്തുക"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"സ്ഥാനം"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"മുകളിലേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"താഴേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ഇടത്തേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"വലത്തേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"സ്ക്രോൾ മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"സ്‌ക്രോൾ പാനൽ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> നിയന്ത്രിത ബക്കറ്റിലേക്ക് നീക്കി"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ചിത്രം അയച്ചു"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ഔദ്യോഗികം 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ടെസ്‌റ്റ്"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"കമ്മ്യൂണൽ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"മേൽനോട്ടമുണ്ട്"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"സ്വകാര്യ സ്പേസ്"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ക്ലോൺ ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 740c78386c3a..4222ce1df348 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Гүйлгэх"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Түр зогсоох"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Байрлал"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Дээш гүйлгэх"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Доош гүйлгэх"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Зүүн тийш гүйлгэх"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Баруун тийш гүйлгэх"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Гүйлгэх горимоос гарах"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Гүйлгэх үйлдлийн түр зуурын самбар"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"зураг илгээсэн"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Ажил 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Туршилт"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Нийтийн"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Хянаж байна"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Ажлын профайл"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Хаалттай орон зай"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 6f741d7b77b9..73fc1b657c97 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल करा"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"थांबवा"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"स्थिती"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"वर स्क्रोल करा"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"खाली स्क्रोल करा"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"डावीकडे स्क्रोल करा"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"उजवीकडे स्क्रोल करा"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल करा मोड मधून बाहेर पडा"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"स्क्रोल करा पॅनल"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> हे प्रतिबंधित बादलीमध्ये ठेवण्यात आले आहे"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"इमेज पाठवली आहे"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ऑफिस ३"</string>
<string name="profile_label_test" msgid="9168641926186071947">"चाचणी"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"सामुदायिक"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"पर्यवेक्षण करत आहे"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"कार्य प्रोफाइल"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"खाजगी स्पेस"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"क्लोन"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 52421557f296..f3160d85e97b 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"အလုပ် ၃"</string>
<string name="profile_label_test" msgid="9168641926186071947">"စမ်းသပ်မှု"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"အများသုံး"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ကြီးကြပ်နေသည်"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"အလုပ်ပရိုဖိုင်"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"သီးသန့်နေရာ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ပုံတူပွားရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3dca9b927c10..a4026db705ce 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rull"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sett på pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Plassér"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rull opp"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rull ned"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rull til venstre"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rull til høyre"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Avslutt rullemodus"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rullepanel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"har sendt et bilde"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Jobb 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Felles"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Med tilsyn"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Jobbprofil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat område"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 13c98551b8ca..5e32b967ec71 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल गर्नुहोस्"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"पज गर्नुहोस्"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"स्थिति"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"माथितिर स्क्रोल गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"तलतिर स्क्रोल गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"बायाँतिर स्क्रोल गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"दायाँतिर स्क्रोल गर्नुहोस्"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल गर्नुहोस् मोडबाट बाहिरिनुहोस्"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"प्यानल स्क्रोल गर्नुहोस्"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"फोटो पठाइयो"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f5e3831a6032..ebdd4c65db20 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrollen"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauzeren"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Positie"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Omhoog scrollen"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Omlaag scrollen"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Naar links scrollen"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Naar rechts scrollen"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Scrollmodus sluiten"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Deelvenster scrollen"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in de bucket RESTRICTED geplaatst"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"heeft een afbeelding gestuurd"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Werk 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Gemeenschappelijk"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Toezicht"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Werkprofiel"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privégedeelte"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index eee243f3f47a..2b91cff7f216 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ବିରତ କରନ୍ତୁ"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"ସ୍ଥିତି"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ଉପରକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ତଳକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ବାମକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ଡାହାଣକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ସ୍କ୍ରୋଲ ମୋଡରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ସ୍କ୍ରୋଲ ପେନେଲ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ଏକ ଛବି ପଠାଯାଇଛି"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ୱାର୍କ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ଟେଷ୍ଟ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"କମ୍ୟୁନାଲ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ନିରୀକ୍ଷଣ କରାଯାଉଛି"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ୱାର୍କ ପ୍ରୋଫାଇଲ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"କ୍ଲୋନ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 6632fb0f1354..5a9f227f6772 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ਸਕ੍ਰੋਲ ਕਰੋ"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ਰੋਕੋ"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"ਸਥਿਤੀ"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ਹੇਠਾਂ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ਸਕ੍ਰੋਲ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ਸਕ੍ਰੋਲ ਪੈਨਲ"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਤਿਬੰਧਿਤ ਖਾਨੇ ਵਿੱਚ ਪਾਇਆ ਗਿਆ ਹੈ"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ਚਿੱਤਰ ਭੇਜਿਆ ਗਿਆ"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"ਕੰਮ ਸੰਬੰਧੀ 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ਜਾਂਚ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"ਭਾਈਚਾਰਕ"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ਕਲੋਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2cdac419ab0d..5f02c1fcc532 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Przewijanie"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Wstrzymaj"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozycja"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Przewiń w górę"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Przewiń w dół"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Przewiń w lewo"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Przewiń w prawo"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Wyłącz tryb przewijania"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Przewiń panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"wysłano obraz"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Służbowy 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Testowy"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Wspólny"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzorujesz"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil służbowy"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Przestrzeń prywatna"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 52dc72c2c280..32d883ab7c29 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rolar"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rolar para cima"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rolar para baixo"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rolar para a esquerda"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rolar para a direita"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de rolagem"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Painel de rolagem"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisionando"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a8400e2837a4..57507df2370a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -2487,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Comum"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"A supervisionar"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 52dc72c2c280..32d883ab7c29 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rolar"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rolar para cima"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rolar para baixo"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rolar para a esquerda"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rolar para a direita"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de rolagem"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Painel de rolagem"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisionando"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8ad6d02e6113..2e6f58dca1df 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Derulează"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Întrerupe"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Poziție"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Derulează în sus"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Derulează în jos"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Derulează la stânga"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Derulează la dreapta"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ieși din modul de derulare"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panou de derulare"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a fost adăugat la grupul RESTRICȚIONATE"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a trimis o imagine"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Serviciu 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Comun"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Supraveghere activă"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil de serviciu"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Spațiu privat"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clonă"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0ee25426bbf6..2beebd7569fc 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Прокрутить"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Приостановить"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Положение"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прокрутка вверх"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прокрутка вниз"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прокрутка влево"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прокрутка вправо"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Отключить режим прокрутки"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панель прокрутки"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Приложение \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" помещено в категорию с ограниченным доступом."</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"Отправлено изображение"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Рабочий 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Тестовый"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Совместный"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Управляющий профиль"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Рабочий профиль"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Частное пространство"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клонированный"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 0d3cd7e4979a..a59187cf62c6 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"අනුචලනය කරන්න"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"විරාම කරන්න"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"ස්ථානය"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ඉහළට අනුචලනය කරන්න"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"පහළට අනුචලනය කරන්න"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"වමට අනුචලනය කරන්න"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"දකුණට අනුචලනය කරන්න"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"අනුචලන ප්‍රකාරයෙන් පිටවන්න"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"අනුචලන පැනලය"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> අවහිර කළ බාල්දියට දමා ඇත"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"රූපයක් එව්වා"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"කාර්යාලය 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"පරීක්ෂණය"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"වාර්ගික"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"අධීක්ෂණය කිරීම"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"කාර්යාල පැතිකඩ"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"රහසිගත අවකාශය"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ක්ලෝන කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e3855d1a6790..999000e6e490 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Posúvať"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pozastaviť"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozícia"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Posunúť nahor"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Posunúť nadol"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Posunúť doľava"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Posunúť doprava"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ukončiť režim posúvania"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Posúvateľný panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balík <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> bol vložený do kontajnera OBMEDZENÉ"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"odoslal(a) obrázok"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"3. pracovný"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Spoločné"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Dohľad"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Pracovný profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Súkromný priestor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index b0ebb5f073b7..4751cb9cfb87 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -2488,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Delo 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Preizkus"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Skupno"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzor"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Delovni profil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Zasebni prostor"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 0f99307da7e3..a15cf4ea3b5c 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -2492,8 +2492,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Puna 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"I përbashkët"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Në mbikëqyrje"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profili i punës"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Hapësira private"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4827c0cc3265..112173ac13ad 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -2274,18 +2274,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Скролујте"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Паузирај"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиција"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Скролуј нагоре"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Скролуј надоле"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Скролуј улево"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Скролуј удесно"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Изађи из режима скроловања"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Окно за скроловање"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"је послао/ла слику"</string>
@@ -2493,8 +2487,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Посао 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Тест"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Заједничко"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Надзире се"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Пословни профил"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватан простор"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клонирано"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c471f065b377..5cb528b5c555 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrolla"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scrolla uppåt"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scrolla nedåt"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scrolla åt vänster"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scrolla åt höger"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Avsluta scrollningsläget"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scrollningspanel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> har placerats i hinken RESTRICTED"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"har skickat en bild"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Arbete 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Allmän"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Kontrollerar"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Jobbprofil"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat utrymme"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klona"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 31f5592ecaad..5207e032fc30 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sogeza"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sitisha"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Nafasi"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Sogeza Juu"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Sogeza Chini"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sogeza Kushoto"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sogeza Kulia"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Funga Hali ya Kusogeza"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Sogeza Kidirisha"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> kimewekwa katika kikundi KILICHODHIBITIWA"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"alituma picha"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Wa 3 wa Kazini"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Jaribio"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Unaoshirikiwa"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Unasimamia"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Wasifu wa kazini"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Sehemu ya faragha"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nakala"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 36b82d99aded..015ce084355b 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"நகர்த்தும்"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"இடைநிறுத்து"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"நிலை"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"மேலே நகர்த்து"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"கீழே நகர்த்து"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"இடப்புறம் நகர்த்து"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"வலப்புறம் நகர்த்து"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"நகர்த்துதல் பயன்முறையில் இருந்து வெளியேறு"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"பேனலை நகர்த்து"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"படம் அனுப்பப்பட்டது"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"பணி 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"பரிசோதனை"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"பொது"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"கண்காணிக்கப்படுகிறது"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"பணிக் கணக்கு"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"ரகசிய இடம்"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"குளோன்"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b67f3828ab72..224ac78c5f92 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"เลื่อน"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"หยุดชั่วคราว"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"วางตำแหน่ง"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"เลื่อนขึ้น"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"เลื่อนลง"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"เลื่อนไปทางซ้าย"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"เลื่อนไปทางขวา"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ออกจากโหมดเลื่อน"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"เลื่อนแผง"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"ใส่ <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ในที่เก็บข้อมูลที่ถูกจำกัดแล้ว"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ส่งรูปภาพ"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"งาน 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"ทดสอบ"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"ส่วนกลาง"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"ผู้ควบคุมดูแล"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"โปรไฟล์งาน"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"พื้นที่ส่วนตัว"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"โคลน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3c380884ceea..9b6ecd30b233 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Mag-scroll"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"I-pause"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisyon"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Mag-scroll Pataas"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Mag-scroll Pababa"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Mag-scroll Pakaliwa"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Mag-scroll Pakanan"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Umalis sa Scroll Mode"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll Panel"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"nagpadala ng larawan"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Trabaho 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Namamahala"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profile sa trabaho"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Pribadong space"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8119d7d2bb2a..ea4cfa644bf3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Kaydırma"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Duraklatma"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Konum"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Yukarı Kaydır"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Aşağı Kaydır"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sola Kaydır"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sağa Kaydır"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Kaydırma Modundan Çık"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Paneli Kaydır"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"bir resim gönderildi"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"İş 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Paylaşılan"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Gözetim"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"İş profili"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Özel alan"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index cda2af43ef12..693b16e88a4c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -2275,18 +2275,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Прокрутити"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Призупинити"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Змінити позицію"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прокрутити вгору"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прокрутити вниз"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прокрутити ліворуч"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прокрутити праворуч"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Вимкнути режим прокручування"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панель прокручування"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" додано в сегмент з обмеженнями"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"надіслано зображення"</string>
@@ -2494,8 +2488,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Робочий профіль 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Тестовий профіль"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Спільний профіль"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Батьківськ. контроль"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Робочий профіль"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватний простір"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Копія профілю"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index fc2bd4b605d1..f7b10bff74eb 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -2486,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Ish 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Umumiy"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Nazorat ostida"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Ish profili"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Maxfiy makon"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nusxalash"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4141af07dc8b..4ee534c6ecfe 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Cuộn"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Tạm dừng"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Vị trí"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Cuộn lên"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Cuộn xuống"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Cuộn sang trái"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Cuộn sang phải"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Thoát khỏi chế độ cuộn"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Cuộn bảng điều khiển"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"đã gửi hình ảnh"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Công việc 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Kiểm thử"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Dùng chung"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Giám sát"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Hồ sơ công việc"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Không gian riêng tư"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nhân bản"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 95dd35fcb0dd..98069c65d235 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"滚动"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暂停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上滚动"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下滚动"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左滚动"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右滚动"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出滚动模式"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"滚动面板"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已被放入受限存储分区"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"发送了一张图片"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"测试"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"监管"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作资料"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"私密空间"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"克隆"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b956da1e856e..038973d760dd 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上捲動"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下捲動"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左捲動"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右捲動"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出捲動模式"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"捲動面板"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已納入受限制的儲存區"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"已傳送圖片"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"監管"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作設定檔"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"私人空間"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index f9abe0e69a46..8ff587bf1e55 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上捲動"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下捲動"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左捲動"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右捲動"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出捲動模式"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"捲動面板"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"已將「<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>」移入受限制的值區"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"傳送了一張圖片"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"通用"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"監督中"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作資料夾"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"私人空間"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 4292eab29a16..3fc910cca43a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -2273,18 +2273,12 @@
<string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Skrola"</string>
<string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Misa"</string>
<string name="accessibility_autoclick_position" msgid="2933660969907663545">"Indawo"</string>
- <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
- <skip />
- <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
- <skip />
+ <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Skrolela Phezulu"</string>
+ <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Skrolela Phansi"</string>
+ <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Skrolela Ngakwesokunxele"</string>
+ <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Skrolela Ngakwesokudla"</string>
+ <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Phuma Kumodi Yokuskrola"</string>
+ <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Iphaneli Yokuskrola"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"uthumele isithombe"</string>
@@ -2492,8 +2486,7 @@
<string name="profile_label_work_3" msgid="4834572253956798917">"Umsebenzi 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Hlola"</string>
<string name="profile_label_communal" msgid="8743921499944800427">"Okomphakathi"</string>
- <!-- no translation found for profile_label_supervising (5649312778545745371) -->
- <skip />
+ <string name="profile_label_supervising" msgid="5649312778545745371">"Ukugada"</string>
<string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Iphrofayela yomsebenzi"</string>
<string name="accessibility_label_private_profile" msgid="1436459319135548969">"Indawo engasese"</string>
<string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Yenza i-Clone"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d2c993aecb0d..647e3dc2d268 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5573,6 +5573,14 @@
<!-- @hide internal use only -->
<declare-styleable name="NotificationProgressBar">
+ <!-- Minimum required drawing width for segments. The drawing width refers to the width
+ after the original segments have been adjusted for the neighboring Points and gaps.
+ This is enforced by stretching the segments that are too short. -->
+ <attr name="segMinWidth" format="dimension" />
+ <!-- The gap between two segments. -->
+ <attr name="segSegGap" format="dimension" />
+ <!-- The gap between a segment and a point. -->
+ <attr name="segPointGap" format="dimension" />
<!-- Draws the tracker on a NotificationProgressBar. -->
<attr name="tracker" format="reference" />
<!-- Height of the tracker. -->
@@ -7580,25 +7588,9 @@
<!-- NotificationProgressDrawable class -->
<!-- ================================== -->
- <!-- Drawable used to render a notification progress bar, with segments and points. -->
- <!-- @hide internal use only -->
- <declare-styleable name="NotificationProgressDrawable">
- <!-- The gap between two segments. -->
- <attr name="segSegGap" format="dimension" />
- <!-- The gap between a segment and a point. -->
- <attr name="segPointGap" format="dimension" />
- </declare-styleable>
-
<!-- Used to config the segments of a NotificationProgressDrawable. -->
<!-- @hide internal use only -->
<declare-styleable name="NotificationProgressDrawableSegments">
- <!-- TODO: b/390196782 - maybe move this to NotificationProgressBar, because that's the only
- place this is used actually. Same for NotificationProgressDrawable.segSegGap/segPointGap
- above. -->
- <!-- Minimum required drawing width. The drawing width refers to the width after
- the original segments have been adjusted for the neighboring Points and gaps. This is
- enforced by stretching the segments that are too short. -->
- <attr name="minWidth" />
<!-- Height of the solid segments. -->
<attr name="height" />
<!-- Height of the faded segments. -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 73681d26f297..8f13ee1ccb49 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -503,6 +503,9 @@ please see styles_device_defaults.xml.
<style name="Widget.Material.Notification.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
<style name="Widget.Material.Notification.NotificationProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
+ <item name="segMinWidth">@dimen/notification_progress_segments_min_width</item>
+ <item name="segSegGap">@dimen/notification_progress_segSeg_gap</item>
+ <item name="segPointGap">@dimen/notification_progress_segPoint_gap</item>
<item name="progressDrawable">@drawable/notification_progress</item>
<item name="trackerHeight">@dimen/notification_progress_tracker_height</item>
</style>
diff --git a/core/tests/coretests/src/android/content/IntentTest.java b/core/tests/coretests/src/android/content/IntentTest.java
index fa1948d9786c..1dbe7f5f245b 100644
--- a/core/tests/coretests/src/android/content/IntentTest.java
+++ b/core/tests/coretests/src/android/content/IntentTest.java
@@ -22,6 +22,7 @@ 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.Bundle;
import android.os.IBinder;
@@ -32,14 +33,21 @@ import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.security.Flags;
import android.util.ArraySet;
+import android.util.Xml;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -277,4 +285,40 @@ public class IntentTest {
assertThat(b2.getBundle("bundle").getClassLoader()).isEqualTo(cl);
}
+ @Test
+ @RequiresFlagsEnabled(android.content.flags.Flags.FLAG_INTENT_SAVE_TO_XML_PACKAGE)
+ public void testSaveToXmlAndRestore() throws Exception {
+ // Create an intent and set fields.
+ Intent original = new Intent();
+ original.setAction(Intent.ACTION_MAIN);
+ original.setComponent(ComponentName.createRelative("com.intent.test", "IntentTest"));
+ original.setData(Uri.parse("content://path/to/file.txt"));
+ original.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ original.setIdentifier("unique_identifier");
+ original.setPackage("com.intent.test");
+ original.addCategory(Intent.CATEGORY_LAUNCHER);
+ original.putExtra("Name", "Some really important data");
+
+ String tag = "intent";
+
+ // Write to xml.
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ TypedXmlSerializer serializer = Xml.resolveSerializer(byteArrayOutputStream);
+ serializer.startDocument(null, true);
+ serializer.startTag(null, tag);
+ original.saveToXml(serializer);
+ serializer.endTag(null, tag);
+ serializer.endDocument();
+
+ // Restore from xml.
+ ByteArrayInputStream byteArrayInputStream =
+ new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+ TypedXmlPullParser parser = Xml.resolvePullParser(byteArrayInputStream);
+ XmlUtils.beginDocument(parser, tag);
+ Intent restored = Intent.restoreFromXml(parser);
+
+ // Verify that the restored intent passed filterEquals on the original.
+ assertTrue(original.filterEquals(restored));
+ }
+
}
diff --git a/core/tests/coretests/src/android/content/pm/UserInfoTest.java b/core/tests/coretests/src/android/content/pm/UserInfoTest.java
index edeea6d85ca6..c84c21557ea4 100644
--- a/core/tests/coretests/src/android/content/pm/UserInfoTest.java
+++ b/core/tests/coretests/src/android/content/pm/UserInfoTest.java
@@ -16,19 +16,44 @@
package android.content.pm;
+import static android.content.pm.UserInfo.FLAG_DEMO;
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MAIN;
+import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.FLAG_SYSTEM;
+import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
+import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
+
import static com.google.common.truth.Truth.assertThat;
+import android.content.pm.UserInfo.UserInfoFlag;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+
@RunWith(AndroidJUnit4.class)
@SmallTest
-public class UserInfoTest {
+public final class UserInfoTest {
+
+ @Rule
+ public final SetFlagsRule flags =
+ new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+
+ @Rule public final Expect expect = Expect.create();
+
@Test
public void testSimple() throws Exception {
final UserInfo ui = new UserInfo(10, "Test", UserInfo.FLAG_GUEST);
@@ -56,9 +81,6 @@ public class UserInfoTest {
assertThat(ui.isInitialized()).isEqualTo(false);
assertThat(ui.isFull()).isEqualTo(false);
assertThat(ui.isMain()).isEqualTo(false);
-
- // Derived dynamically
- assertThat(ui.canHaveProfile()).isEqualTo(false);
}
@Test
@@ -68,4 +90,64 @@ public class UserInfoTest {
assertThat(ui.toString()).isNotEmpty();
assertThat(ui.toFullString()).isNotEmpty();
}
+
+ @Test
+ @DisableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL)
+ public void testCanHaveProfile_flagProfilesForAllDisabled() {
+ expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0));
+ expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST));
+ expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN));
+ expectCannotHaveProfile("non-main user", createTestUserInfo(FLAG_FULL));
+ expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO));
+ expectCannotHaveProfile("restricted user",
+ createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL));
+ expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE));
+ expectCanHaveProfile("(full) system user that's also main user",
+ createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN));
+ expectCannotHaveProfile("headless system user that's not main user",
+ createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM));
+ }
+
+ @Test
+ @EnableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL)
+ public void testCanHaveProfile_flagProfilesForAllEnabled() {
+ expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0));
+ expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST));
+ expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN));
+ expectCanHaveProfile("non-main user", createTestUserInfo(FLAG_FULL));
+ expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO));
+ expectCannotHaveProfile("restricted user",
+ createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL));
+ expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE));
+ expectCanHaveProfile("(full) system user that's also main user",
+ createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN));
+ expectCannotHaveProfile("headless system user that's not main user",
+ createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM));
+ }
+
+ /**
+ * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given
+ * {@code flags}.
+ */
+ private UserInfo createTestUserInfo(@UserInfoFlag int flags) {
+ return new UserInfo(10, "Test", flags);
+ }
+
+ /**
+ * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given
+ * {@code userType} and {@code flags}.
+ */
+ private UserInfo createTestUserInfo(String userType, @UserInfoFlag int flags) {
+ return new UserInfo(10, "Test", /* iconPath= */ null, flags, userType);
+ }
+
+ private void expectCanHaveProfile(String description, UserInfo user) {
+ expect.withMessage("canHaveProfile() on %s (%s)", description, user)
+ .that(user.canHaveProfile()).isTrue();
+ }
+
+ private void expectCannotHaveProfile(String description, UserInfo user) {
+ expect.withMessage("canHaveProfile() on %s (%s)", description, user)
+ .that(user.canHaveProfile()).isFalse();
+ }
}
diff --git a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java b/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
index 45864b01c795..e06ff98b0384 100644
--- a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
+++ b/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
@@ -16,10 +16,14 @@
package android.security.advancedprotection;
+import static android.os.UserManager.DISALLOW_CELLULAR_2G;
+import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
import static android.security.advancedprotection.AdvancedProtectionManager.ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG;
import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE;
import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE;
import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE;
import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION;
import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING;
import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN;
@@ -37,6 +41,9 @@ import org.junit.runners.JUnit4;
public class AdvancedProtectionManagerTest {
private static final int FEATURE_ID_INVALID = -1;
private static final int SUPPORT_DIALOG_TYPE_INVALID = -1;
+ //TODO(b/378931989): Switch to android.app.admin.DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY
+ //when the appropriate flag is launched.
+ private static final String MEMORY_TAGGING_POLICY = "memoryTagging";
@Test
public void testCreateSupportIntent_validFeature_validTypeUnknown_createsIntent() {
@@ -94,4 +101,44 @@ public class AdvancedProtectionManagerTest {
AdvancedProtectionManager.createSupportIntent(FEATURE_ID_INVALID,
SUPPORT_DIALOG_TYPE_INVALID));
}
+
+ @Test
+ public void testCreateSupportIntentForPolicy_2g_typeUnknown_createsIntentForDisabledSetting() {
+ Intent intent = AdvancedProtectionManager
+ .createSupportIntentForPolicyIdentifierOrRestriction(
+ DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+ assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+ assertEquals(FEATURE_ID_DISALLOW_CELLULAR_2G, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+ assertEquals(SUPPORT_DIALOG_TYPE_DISABLED_SETTING, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+ }
+
+ @Test
+ public void testCreateSupportIntentForPolicy_mte_typeUnknown_createsIntentForDisabledSetting() {
+ Intent intent = AdvancedProtectionManager
+ .createSupportIntentForPolicyIdentifierOrRestriction(
+ MEMORY_TAGGING_POLICY, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+ assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+ assertEquals(FEATURE_ID_ENABLE_MTE, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+ assertEquals(SUPPORT_DIALOG_TYPE_DISABLED_SETTING, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+ }
+
+ @Test
+ public void
+ testCreateSupportIntentForPolicy_unknownSources_typeUnknown_createsIntentForUnknown() {
+ Intent intent = AdvancedProtectionManager
+ .createSupportIntentForPolicyIdentifierOrRestriction(
+ DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+ assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+ assertEquals(FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+ assertEquals(SUPPORT_DIALOG_TYPE_UNKNOWN, intent.getIntExtra(
+ EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+ }
}
diff --git a/core/tests/coretests/src/android/window/BackTouchTrackerTest.kt b/core/tests/coretests/src/android/window/BackTouchTrackerTest.kt
index ad68e385459e..381b566018c7 100644
--- a/core/tests/coretests/src/android/window/BackTouchTrackerTest.kt
+++ b/core/tests/coretests/src/android/window/BackTouchTrackerTest.kt
@@ -37,7 +37,7 @@ class BackTouchTrackerTest {
fun generatesProgress_onStart() {
val linearTracker = linearTouchTracker()
linearTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0f, BackEvent.EDGE_LEFT)
- val event = linearTracker.createStartEvent()
+ val event = linearTracker.createStartEvent(null)
assertEquals(0f, event.progress, 0f)
}
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 66524d1c1d2a..215c1623a530 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -695,7 +695,8 @@ public class WindowOnBackInvokedDispatcherTest {
/* frameTimeMillis = */ 0,
/* progress = */ progress,
/* triggerBack = */ false,
- /* swipeEdge = */ BackEvent.EDGE_LEFT);
+ /* swipeEdge = */ BackEvent.EDGE_LEFT,
+ /* departingAnimationTarget = */ null);
}
private void verifyImeCallackRegistrations() throws RemoteException {
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index b6a1501831c0..19455a313a9d 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -211,3 +211,10 @@ flag {
description: "Makes the split divider snap 'magnetically' to available snap points during drag"
bug: "383631946"
}
+
+flag {
+ name: "enable_dynamic_insets_for_app_launch"
+ namespace: "multitasking"
+ description: "Enables dynamic insets for app launch so the window is properly cropped"
+ bug: "336511494"
+}
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 1491c70023e7..05c4c56a5c81 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Die appkieslys kan hier gevind word"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Maak werkskermvensters oop om verskeie apps terselfdertyd oop te maak"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Keer enige tyd terug na volskerm vanaf die appkieslys"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sien en doen meer"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Sleep ’n ander app in vir verdeelde skerm"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Apphandvatsel"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Werkskermvensters"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Verdeelde skerm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Sweef"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
<string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (werkskermvensters)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Verander grootte"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 8bd602c08508..450419dcc40d 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"የመተግበሪያ ምናሌው እዚህ መገኘት ይችላል"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"በርካታ መተግበሪያዎችን በአንድ ላይ ለመክፈት ወደ የዴስክቶፕ መስኮት ይግቡ"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"በማንኛውም ጊዜ ከመተግበሪያ ምናሌው ላይ ወደ ሙሉ ገጽ እይታ ይመለሱ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ተጨማሪ ይመልከቱ እና ያድርጉ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገፅ ሌላ መተግበሪያ ይጎትቱ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"የመተግበሪያ መያዣ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ዴስክቶፕ መስኮት"</string>
<string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገፅ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
<string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ዴስክቶፕ መስኮት)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"መጠን ቀይር"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 6872df6acbc9..b1826db57a2c 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"এপৰ মেনু ইয়াত বিচাৰি পোৱা যাব"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"একেলগে একাধিক এপ্‌ খুলিবলৈ ডেস্কটপ ৱিণ্ড’ৱিঙলৈ যাওক"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"এপৰ মেনুৰ পৰা যিকোনো সময়তে পূৰ্ণ স্ক্ৰীনলৈ উভতি যাওক"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"চাওক আৰু অধিক কৰক"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"বিভাজিত স্ক্ৰীনৰ বাবে অন্য এটা এপ্‌ টানি আনি এৰক"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"এপৰ হেণ্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ডেস্কটপ ৱিণ্ড’ৱিং"</string>
<string name="split_screen_text" msgid="1396336058129570886">"বিভাজিত স্ক্ৰীন"</string>
<string name="more_button_text" msgid="3655388105592893530">"অধিক"</string>
<string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
<string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ডেস্কটপ ৱিণ্ড’ৱিং)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"আকাৰ সলনি কৰক"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 46309411d0c9..c5493b573d0f 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Tətbiq menyusunu burada tapa bilərsiniz"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Bir neçə tətbiqi birlikdə açmaq üçün masaüstü pəncərə rejiminə daxil olun"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"İstənilən vaxt tətbiq menyusundan tam ekrana qayıdın"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ardını görün və edin"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Bölünmüş ekran üçün başqa tətbiq sürüşdürün"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Tətbiq ləqəbi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Masaüstü pəncərə rejimi"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ardı"</string>
<string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
<string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Masaüstü pəncərə rejimi)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ölçüsünü dəyişin"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</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 4af564833ba1..307c47ab48eb 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meni aplikacije možete da pronađete ovde"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Uđite u prozorski prikaz za računare da biste istovremeno otvorili više aplikacija"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Vratite se na ceo ekran bilo kada iz menija aplikacije"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vidite i uradite više"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Prevucite drugu aplikaciju da biste koristili podeljeni ekran"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Prozorski prikaz za računare"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Još"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promeni razmeru"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prozorski prikaz za računare)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Prilagodi"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 7719396b01d1..c53e37c67cfc 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Меню праграмы шукайце тут"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Каб адкрыць некалькі праграм адначасова, увайдзіце ў рэжым вокнаў працоўнага стала"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вы можаце вярнуцца ў поўнаэкранны рэжым у любы час з меню праграмы"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Адначасова выконвайце розныя задачы"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Перацягніце іншую праграму, каб выкарыстоўваць падзелены экран"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Маркер праграмы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Рэжым вокнаў працоўнага стала"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Падзяліць экран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Яшчэ"</string>
<string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (рэжым вокнаў працоўнага стала)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Змяніць памер"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 514556e30fe0..29af2ed1c38b 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Можете да намерите менюто на приложението тук"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Активирайте режима за настолни компютри, за да отворите няколко приложения едновременно"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Преминете към цял екран по всяко време от менюто на приложението"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Преглеждайте и правете повече неща"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Преместете друго приложение с плъзгане, за да преминете в режим за разделен екран"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Манипулатор за приложението"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Режим за настолни компютри"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Разделяне на екрана"</string>
<string name="more_button_text" msgid="3655388105592893530">"Още"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
<string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим за настолни компютри)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Нов размер"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 23c467c0b4ba..537afdcc6de4 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ovdje možete pronaći meni aplikacije"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Otvorite prikaz u prozorima na računalu da biste otvorili više aplikacija zajedno"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Povratak na prikaz preko cijelog ekrana bilo kada putem menija aplikacije"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Pogledajte i učinite više"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Prevucite još jednu aplikaciju za podijeljeni ekran"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Prikaz u prozorima na računalu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Više"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 893d16e6155e..42b07ef3d049 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Pots trobar el menú de l\'aplicació aquí"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accedeix a l\'enfinestrament d\'escriptori per obrir diverses aplicacions alhora"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Torna a la pantalla completa en qualsevol moment des del menú de l\'aplicació"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Consulta i fes més coses"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrossega una altra aplicació per utilitzar la pantalla dividida"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador de l\'aplicació"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Enfinestrament d\'escriptori"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Més"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotant"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
<string name="close_text" msgid="4986518933445178928">"Tanca"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (enfinestrament d\'escriptori)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index a96344a0a365..44548682cbbc 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Najdete tu nabídku aplikace"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Pokud chcete otevřít několik aplikací současně, přejděte do režimu s okny na ploše"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Na celou obrazovku se můžete kdykoli vrátit z nabídky aplikace"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lepší zobrazení a více možností"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Přetáhnutím druhé aplikace použijete rozdělenou obrazovku"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Popisovač aplikace"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Okna na ploše"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Rozdělená obrazovka"</string>
<string name="more_button_text" msgid="3655388105592893530">"Více"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
<string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (okna na ploše)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 7d28fc842e59..4d14f93d7b77 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Appmenuen kan findes her"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Brug vinduer på skrivebordet for at åbne flere apps på én gang"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Gå tilbage til fuld skærm når som helst via appmenuen"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gør mere"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Træk en anden app hertil for at bruge opdelt skærm"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Apphåndtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Vinduer på skrivebordet"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Opdelt skærm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mere"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svævende"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
<string name="close_text" msgid="4986518933445178928">"Luk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (vinduer på skrivebordet)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Tilpas størrelse"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 4cc11243b8bd..82bbfc4eff29 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Das App-Menü findest du hier"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Über ein Desktop-Freiform-Fenster kannst du mehrere Apps gleichzeitig öffnen"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Über das App-Menü kannst du jederzeit zum Vollbildmodus zurückkehren"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Mehr sehen und erledigen"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Für Splitscreen-Modus weitere App hineinziehen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App-Ziehpunkt"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop-Freiform-Fenster"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Splitscreen"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mehr"</string>
<string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
<string name="close_text" msgid="4986518933445178928">"Schließen"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop-Freiform-Fenster)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Größe ändern"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 0fb17ecdb278..a8696aff1f0c 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Μπορείτε να βρείτε το μενού εφαρμογών εδώ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Μεταβείτε στην προσαρμογή σε παράθυρο στην επιφάνεια εργασίας, για να ανοίξετε πολλές εφαρμογές μαζί"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Επιστρέψτε στην πλήρη οθόνη ανά πάσα στιγμή από το μενού της εφαρμογής"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Δείτε και κάντε περισσότερα"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Σύρετε σε μια άλλη εφαρμογή για διαχωρισμό οθόνης."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Λαβή εφαρμογής"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Προσαρμογή σε παράθυρο στην επιφάνεια εργασίας"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Διαχωρισμός οθόνης"</string>
<string name="more_button_text" msgid="3655388105592893530">"Περισσότερα"</string>
<string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
<string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Προσαρμογή σε παράθυρο στην επιφάνεια εργασίας)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Αλλαγή μεγέθους"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 2087bb4ad579..61b68a2b2515 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 2087bb4ad579..61b68a2b2515 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 2087bb4ad579..61b68a2b2515 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App handle"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"More"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 36086578dd4d..c0e4eb36b541 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Rakenduse menüü leiate siit"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Mitme rakenduse koos avamiseks kasutage töölaua aknaid"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Saate rakenduse menüüst igal ajal täisekraanile naasta"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vaadake ja tehke rohkem"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Lohistage muusse rakendusse, et jagatud ekraanikuva kasutada"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Rakenduse element"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Töölaua aknad"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Jagatud ekraanikuva"</string>
<string name="more_button_text" msgid="3655388105592893530">"Rohkem"</string>
<string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
<string name="close_text" msgid="4986518933445178928">"Sule"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (töölaua aknad)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index bf5c8f95cfb3..4879965d1ae7 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن تک‌ضرب بزنید"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن تک‌ضرب بزنید."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"منو برنامه را می‌توانید اینجا ببینید"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"برای باز کردن هم‌زمان چند برنامه، وارد پردازش پنجره‌ای رایانه شوید"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"هروقت خواستید از منو برنامه به حالت تمام‌صفحه برگردید"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه به‌طور هم‌زمان استفاده کنید"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"برای حالت صفحهٔ دونیمه، در برنامه‌ای دیگر بکشید"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"دستگیره برنامه"</string>
<string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"تمام‌صفحه"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"پردازش پنجره‌ای رایانه"</string>
<string name="split_screen_text" msgid="1396336058129570886">"صفحهٔ دونیمه"</string>
<string name="more_button_text" msgid="3655388105592893530">"بیشتر"</string>
<string name="float_button_text" msgid="9221657008391364581">"شناور"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
<string name="close_text" msgid="4986518933445178928">"بستن"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (پردازش پنجره‌ای رایانه)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغییر اندازه"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index a32e4fab9d81..8fd6b1bacbbe 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Sovellusvalikko löytyy täältä"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Siirry työpöydän ikkunointiin, niin voit avata useita sovelluksia kerralla"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Voit palata koko näytön tilaan milloin tahansa sovellusvalikosta"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Näe ja tee enemmän"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Käytä jaettua näyttöä vetämällä tähän toinen sovellus"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Sovelluksen tunnus"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Työpöydän ikkunointi"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Jaettu näyttö"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lisää"</string>
<string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
<string name="close_text" msgid="4986518933445178928">"Sulje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (työpöydän ikkunointi)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Muuta kokoa"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 7037377156c6..b729ececfccd 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Le menu de l\'appli se trouve ici"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accéder au fenêtrage du bureau pour ouvrir plusieurs applis simultanément"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revenir au mode Plein écran à tout moment à partir du menu de l\'appli"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et en faire plus"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Fenêtrage du bureau"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string>
<string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flottant"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage du bureau)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index fb2ebfd55583..ed87a1388304 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Le menu de l\'application se trouve ici"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Utiliser le fenêtrage de bureau pour ouvrir plusieurs applications simultanément"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revenir en plein écran à tout moment depuis le menu de l\'application"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et interagir plus"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Fenêtrage de bureau"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string>
<string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flottante"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage de bureau)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 895cf47e3d53..a2b871120464 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Aquí podes ver o menú da aplicación"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Vai ao escritorio baseado en ventás se queres abrir varias aplicacións á vez"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Volve á pantalla completa en calquera momento desde o menú da aplicación"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ver e facer máis"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrastra outra aplicación para usar a pantalla dividida"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador da aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Escritorio baseado en ventás"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Máis"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
<string name="close_text" msgid="4986518933445178928">"Pechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (escritorio baseado en ventás)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar tamaño"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 9c8cf96be294..ddef9e1fd07b 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -43,10 +43,8 @@
<string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ડાબે 50%"</string>
<string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ડાબે 30%"</string>
<string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"જમણી સ્ક્રીન સ્ક્રીન"</string>
- <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
- <skip />
- <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
- <skip />
+ <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"એકદમ ઉપરની ઍપને એકદમ નીચેની સાથે સ્વૉપ કરો"</string>
+ <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ડાબી ઍપને જમણી સાથે સ્વૉપ કરો"</string>
<string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"શીર્ષ પૂર્ણ સ્ક્રીન"</string>
<string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"શીર્ષ 70%"</string>
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string>
@@ -102,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ઍપ મેનૂ અહીં જોવા મળી શકે છે"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"એકથી વધુ ઍપ એકસાથે ખોલવા માટે ડેસ્કટૉપ વિન્ડોઇંગ દાખલ કરો"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ઍપ મેનૂમાંથી કોઈપણ સમયે પૂર્ણ સ્ક્રીન પર પાછા ફરો"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"જુઓ અને બીજું ઘણું કરો"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"વિભાજિત સ્ક્રીન માટે કોઈ અન્ય ઍપમાં ખેંચો"</string>
@@ -116,20 +113,15 @@
<string name="letterbox_restart_restart" msgid="8529976234412442973">"ફરી શરૂ કરો"</string>
<string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ફરીથી બતાવશો નહીં"</string>
<string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"આ ઍપને ખસેડવા માટે\nબે વાર ટૅપ કરો"</string>
- <!-- no translation found for maximize_button_text (8106849394538234709) -->
- <skip />
- <!-- no translation found for restore_button_text (5377571986086775288) -->
- <skip />
- <!-- no translation found for minimize_button_text (5213953162664451152) -->
- <skip />
- <!-- no translation found for close_button_text (4544839489310949894) -->
- <skip />
+ <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કદ મહત્તમ કરો"</string>
+ <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>ને રિસ્ટોર કરો"</string>
+ <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કદ ન્યૂનતમ કરો"</string>
+ <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> બંધ કરો"</string>
<string name="back_button_text" msgid="1469718707134137085">"પાછળ"</string>
<string name="handle_text" msgid="4419667835599523257">"ઍપનું હૅન્ડલ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ઍપનું આઇકન"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ડેસ્કટૉપ વિન્ડોઇંગ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="more_button_text" msgid="3655388105592893530">"વધુ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string>
@@ -142,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
<string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ડેસ્કટૉપ વિન્ડોઇંગ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"કદ બદલો"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
@@ -161,14 +152,10 @@
<string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ડાબી બાજુ વિન્ડોનું કદ બદલો"</string>
<string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"જમણી બાજુ વિન્ડોનું કદ બદલો"</string>
<string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"વિન્ડોનું કદ મહત્તમ કરો અથવા રિસ્ટોર કરો"</string>
- <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
- <skip />
- <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
- <skip />
+ <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ઍપની વિન્ડોનું કદ મહત્તમ કરો"</string>
+ <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"વિન્ડોનું કદ રિસ્ટોર કરો"</string>
+ <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ઍપની વિન્ડોનું કદ ન્યૂનતમ કરો"</string>
+ <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ઍપની વિન્ડો બંધ કરો"</string>
<string name="open_by_default_settings_text" msgid="2526548548598185500">"\'ડિફૉલ્ટ તરીકે ખોલો\' સેટિંગ"</string>
<string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"આ ઍપ માટે વેબ લિંક ખોલવાની રીત પસંદ કરો"</string>
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ઍપમાં"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 985dafffa68a..bbe43a1727f8 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ऐप्लिकेशन मेन्यू यहां पाया जा सकता है"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एक साथ कई ऐप्लिकेशन खोलने के लिए, डेस्कटॉप विंडोविंग का इस्तेमाल करें"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ऐप्लिकेशन मेन्यू से फ़ुल स्क्रीन मोड पर किसी भी समय वापस जाएं"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पूरी जानकारी लेकर, बेहतर तरीके से काम करें"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रीन का इस्तेमाल करने के लिए, किसी अन्य ऐप्लिकेशन को खींचें और छोड़ें"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ऐप्लिकेशन का हैंडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"डेस्कटॉप विंडोविंग"</string>
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन मोड"</string>
<string name="more_button_text" msgid="3655388105592893530">"ज़्यादा देखें"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
<string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोविंग)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"साइज़ बदलें"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 4640bf3b8293..80ee56102cf2 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Izbornik aplikacije možete pronaći ovdje"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Otvorite prikaz u prozorima na računalu da biste otvorili više aplikacija zajedno"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Vratite se na cijeli zaslon bilo kad iz izbornika aplikacije"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Gledajte i učinite više"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Povucite drugu aplikaciju unutra da biste podijelili zaslon"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Pokazivač aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Prikaz u prozorima na računalu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Razdvojeni zaslon"</string>
<string name="more_button_text" msgid="3655388105592893530">"Više"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 711e2f0bfbbe..d24e4da8c982 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Az alkalmazásmenü itt található"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Asztali ablakkezelési módba lépve több alkalmazást nyithat meg egyidejűleg"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Az alkalmazásmenüből bármikor visszatérhet a teljes képernyőre"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Több mindent láthat és tehet"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Húzzon ide egy másik alkalmazást az osztott képernyő használatához"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App fogópontja"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Asztali ablakkezelési mód"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Osztott képernyő"</string>
<string name="more_button_text" msgid="3655388105592893530">"Továbbiak"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
<string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Asztali ablakkezelési mód)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Átméretezés"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index d7b1b07b6917..6bc3c37cadf4 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Հավելվածի ընտրացանկն այստեղ է"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Անցեք համակարգչային պատուհաններին՝ միաժամանակ մի քանի հավելված բացելու համար"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ցանկացած ժամանակ հավելվածի ընտրացանկից վերադարձեք լիաէկրան ռեժիմ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Միաժամանակ կատարեք մի քանի առաջադրանք"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Քաշեք մյուս հավելվածի մեջ՝ էկրանի տրոհումն օգտագործելու համար"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Հավելվածի կեղծանուն"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Համակարգչային պատուհաններ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Տրոհված էկրան"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ավելին"</string>
<string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
<string name="close_text" msgid="4986518933445178928">"Փակել"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (համակարգչային պատուհաններ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Փոխել չափը"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 1d1927f9dfbc..c15c2ea6600b 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menu aplikasi dapat ditemukan di sini"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Masuk ke mode jendela desktop untuk membuka beberapa aplikasi secara bersamaan"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kembali ke layar penuh kapan saja dari menu aplikasi"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih banyak hal"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Tarik aplikasi lain untuk menggunakan layar terpisah"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Penanganan aplikasi"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Mode jendela desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Layar Terpisah"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lainnya"</string>
<string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Mode jendela desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah ukuran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index e94a4c8a08ea..7d98d3b01fc2 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Hér finnurðu forritavalmyndina"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Kveiktu á gluggastillingu í tölvu til að opna mörg forrit samtímis"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Þú getur skipt aftur í allan skjáinn hvenær sem er af forritavalmyndinni"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sjáðu og gerðu meira"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dragðu annað forrit inn til að nota skjáskiptingu"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Handfang forrits"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Gluggastilling í tölvu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Skjáskipting"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meira"</string>
<string name="float_button_text" msgid="9221657008391364581">"Reikult"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
<string name="close_text" msgid="4986518933445178928">"Loka"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (gluggastilling í tölvu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Breyta stærð"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 5f8334fa011c..72f805693146 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Il menu dell\'app si trova qui"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Attiva il windowing del desktop per aprire più app contemporaneamente"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Torna allo schermo intero in qualsiasi momento dal menu dell\'app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Visualizza più contenuti e fai di più"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Trascina in un\'altra app per usare lo schermo diviso"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Punto di manipolazione app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Windowing del desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Schermo diviso"</string>
<string name="more_button_text" msgid="3655388105592893530">"Altro"</string>
<string name="float_button_text" msgid="9221657008391364581">"Mobile"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
<string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing del desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ridimensiona"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 1a73dd3b7715..c95ec4ee25a3 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"アプリメニューはここにあります"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"デスクトップ ウィンドウに切り替えて複数のアプリを同時に開けます"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"アプリメニューからいつでも全画面表示に戻れます"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"表示を拡大して機能を強化"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"分割画面にするにはもう 1 つのアプリをドラッグしてください"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"アプリハンドル"</string>
<string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"デスクトップ ウィンドウ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分割画面"</string>
<string name="more_button_text" msgid="3655388105592893530">"その他"</string>
<string name="float_button_text" msgid="9221657008391364581">"フローティング"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
<string name="close_text" msgid="4986518933445178928">"閉じる"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(デスクトップ ウィンドウ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"サイズ変更"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 4bbfaefb36a2..0c7264cf9ede 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"აპის მენიუ შეგიძლიათ იხილოთ აქ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"რამდენიმე აპის ერთდროულად გასახსნელად შედით დესკტოპის ფანჯრის რეჟიმში"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"სრულ ეკრანზე ნებისმიერ დროს შეგიძლიათ დაბრუნდეთ აპის მენიუდან"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"მეტის ნახვა და გაკეთება"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ეკრანის გასაყოფად ჩავლებით გადაიტანეთ სხვა აპში"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"აპის იდენტიფიკატორი"</string>
<string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"დესკტოპის ფანჯრის რეჟიმი"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ეკრანის გაყოფა"</string>
<string name="more_button_text" msgid="3655388105592893530">"სხვა"</string>
<string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
<string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (დესკტოპის ფანჯრის რეჟიმი)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ზომის შეცვლა"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 2f6404d4680d..c1085db12f08 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Қолданба мәзірін осы жерден табуға болады."</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бірнеше қолданбаны бірге ашу үшін жұмыс үстелі көрінісіне кіріңіз."</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Қолданба мәзірінен кез келген уақытта толық экранға оралыңыз."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Қосымша ақпаратты қарап, әрекеттер жасау"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Экранды бөлу үшін басқа қолданбаға өтіңіз."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Жұмыс үстелі көрінісі"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string>
<string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string>
<string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
<string name="close_text" msgid="4986518933445178928">"Жабу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (жұмыс үстелі көрінісі)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлшемін өзгерту"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index d3942fdc1e6c..afbd9e0c9422 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"អាចរកឃើញម៉ឺនុយកម្មវិធីនៅទីនេះ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ចូលមុខងារវិនដូកុំព្យូទ័រ ដើម្បីបើកកម្មវិធីច្រើនជាមួយគ្នា"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ត្រឡប់ទៅអេក្រង់ពេញវិញនៅពេលណាក៏បានពីម៉ឺនុយកម្មវិធី"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"មើលឃើញ និងធ្វើបានកាន់តែច្រើន"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"អូស​កម្មវិធី​មួយ​ទៀត​ចូល ដើម្បី​ប្រើ​មុខងារ​បំបែកអេក្រង់"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ឈ្មោះអ្នកប្រើប្រាស់កម្មវិធី"</string>
<string name="app_icon_text" msgid="2823268023931811747">"រូប​កម្មវិធី"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់​ពេញ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"មុខងារវិនដូកុំព្យូទ័រ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"មុខងារ​បំបែក​អេក្រង់"</string>
<string name="more_button_text" msgid="3655388105592893530">"ច្រើនទៀត"</string>
<string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរ​​សមាមាត្រ"</string>
<string name="close_text" msgid="4986518933445178928">"បិទ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (មុខងារវិនដូកុំព្យូទ័រ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ប្ដូរ​ទំហំ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index fb15e34d934b..34076e8ecebe 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ಆ್ಯಪ್ ಮೆನುವನ್ನು ಇಲ್ಲಿ ಕಾಣಬಹುದು"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ಹಲವು ಆ್ಯಪ್‌ಗಳನ್ನು ಒಟ್ಟಿಗೆ ತೆರೆಯಲು ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್ ಅನ್ನು ನಮೂದಿಸಿ"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ಆ್ಯಪ್ ಮೆನುವಿನಿಂದ ಯಾವಾಗ ಬೇಕಾದರೂ ಫುಲ್‌ಸ್ಕ್ರೀನ್‌ಗೆ ಹಿಂತಿರುಗಿ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ನೋಡಿ ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ಸ್ಪ್ಲಿಟ್‌ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ನಲ್ಲಿ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ಆ್ಯಪ್ ಹ್ಯಾಂಡಲ್"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್‌ಸ್ಕ್ರೀನ್"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="more_button_text" msgid="3655388105592893530">"ಇನ್ನಷ್ಟು"</string>
<string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index dbfd32a7dcb1..a0fa7e480663 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"앱 메뉴는 여기에서 찾을 수 있습니다."</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"데스크톱 윈도윙을 실행하여 여러 앱을 함께 열 수 있습니다."</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"언제든지 앱 메뉴에서 전체 화면으로 돌아갈 수 있습니다."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"더 많은 정보를 보고 더 많은 작업을 처리하세요"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"화면 분할을 사용하려면 다른 앱을 드래그해 가져옵니다."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"앱 핸들"</string>
<string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"데스크톱 윈도잉"</string>
<string name="split_screen_text" msgid="1396336058129570886">"화면 분할"</string>
<string name="more_button_text" msgid="3655388105592893530">"더보기"</string>
<string name="float_button_text" msgid="9221657008391364581">"플로팅"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
<string name="close_text" msgid="4986518933445178928">"닫기"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(데스크톱 윈도윙)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"크기 조절"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 36194cdaaa47..629070cbe810 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Колдонмонун менюсун ушул жерден таба аласыз"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бир убакта бир нече колдонмону ачуу үчүн иш тактанын терезелери режимине өтүңүз"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Каалаган убакта колдонмонун менюсунан толук экранга кайта аласыз"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Көрүп, көбүрөөк нерселерди жасаңыз"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Экранды бөлүү үчүн башка колдонмону сүйрөңүз"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Колдонмонун маркери"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Иш тактанын терезелери"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлүү"</string>
<string name="more_button_text" msgid="3655388105592893530">"Дагы"</string>
<string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
<string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Иш тактанын терезелери)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлчөмүн өзгөртүү"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 671f92447204..f2d0e6bd7af4 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ສາມາດເບິ່ງເມນູແອັບໄດ້ບ່ອນນີ້"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ເຂົ້າສູ່ໜ້າຈໍເດັສທັອບເພື່ອເປີດຫຼາຍແອັບພ້ອມກັນ"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ກັບຄືນໄປຫາໂໝດເຕັມຈໍໄດ້ທຸກເວລາຈາກເມນູແອັບ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ເບິ່ງ ແລະ ເຮັດຫຼາຍຂຶ້ນ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ລາກໄປໄວ້ໃນແອັບອື່ນເພື່ອແບ່ງໜ້າຈໍ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ຊື່ຜູ້ໃຊ້ແອັບ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ໜ້າຈໍເດັສທັອບ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ແບ່ງໜ້າຈໍ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ເພີ່ມເຕີມ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
<string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ໜ້າຈໍເດັສທັອບ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ປັບຂະໜາດ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 794c5ab02c19..ed4b14cd94dd 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Programos meniu rasite čia"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Įjunkite versijos staliniams kompiuteriams rodinį, kad galėtumėte vienu metu atidaryti kelias programas"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Bet kada iš programos meniu grįžkite į viso ekrano režimą"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daugiau turinio ir funkcijų"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Vilkite kitoje programoje, kad galėtumėte naudoti išskaidyto ekrano režimą"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Programos kreipinys"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Versijos staliniams kompiuteriams rodinys"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Išskaidyto ekrano režimas"</string>
<string name="more_button_text" msgid="3655388105592893530">"Daugiau"</string>
<string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
<string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ (versijos staliniams kompiuteriams rodinys)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Pakeisti dydį"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 5b44112c76d5..c24b43a686c3 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Šeit ir pieejama lietotņu izvēlne"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Lai atvērtu vairākas lietotnes vienlaikus, pārejiet uz darbvirsmas logošanu"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"No lietotnes izvēlnes varat jebkurā brīdī atgriezties pilnekrāna režīmā."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Uzziniet un paveiciet vairāk"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Lai izmantotu sadalītu ekrānu, ievelciet vēl vienu lietotni"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Lietotnes turis"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Darbvirsmas logošana"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Sadalīt ekrānu"</string>
<string name="more_button_text" msgid="3655388105592893530">"Vairāk"</string>
<string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
<string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (darbvirsmas logošana)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Mainīt lielumu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 96bf9b67144e..06ed3232514b 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Менито со апликации може да го најдете овде"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Влезете во режимот со прозорци на работната површина за да отворите повеќе апликации заедно"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вратете се на цел екран од менито со апликации кога сакате"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Погледнете и направете повеќе"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Повлечете друга апликација за поделен екран"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Прекар на апликацијата"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Режим со прозорци на работната површина"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Поделен екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Повеќе"</string>
<string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
<string name="close_text" msgid="4986518933445178928">"Затворете"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим со прозорци на работната површина)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Смени големина"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 8085601076ef..dd4ec1bbf1cd 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ആപ്പ് മെനു ഇവിടെ കണ്ടെത്താനാകും"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ഒന്നിലധികം ആപ്പുകൾ ഒരുമിച്ച് തുറക്കാൻ ഡെസ്‌ക്‌‌ടോപ്പ് വിൻഡോയിംഗിൽ പ്രവേശിക്കുക"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ആപ്പ് മെനുവിൽ നിന്ന് ഏതുസമയത്തും പൂർണ്ണ സ്‌ക്രീനിലേക്ക് മടങ്ങുക"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"കൂടുതൽ കാണുക, ചെയ്യുക"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"സ്‌ക്രീൻ വിഭജന മോഡിന്, മറ്റൊരു ആപ്പ് വലിച്ചിടുക"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ആപ്പ് ഹാൻഡിൽ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ്"</string>
<string name="split_screen_text" msgid="1396336058129570886">"സ്‌ക്രീൻ വിഭജനം"</string>
<string name="more_button_text" msgid="3655388105592893530">"കൂടുതൽ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
<string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ്)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്‌ക്രീൻ വലുതാക്കുക"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"വലുപ്പം മാറ്റുക"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 5efe62d7d837..8683827ae004 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Аппын цэсийг эндээс олох боломжтой"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Олон аппыг хамтад нь нээхийн тулд дэлгэцийн цонх үүсгэх гэж орно уу"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Аппын цэсээс бүтэн дэлгэц рүү хүссэн үедээ буцна уу"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Харж илүү ихийг хий"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Дэлгэц хуваах горимд ашиглахын тулд өөр аппыг чирнэ үү"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Аппын бариул"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Дэлгэцийн цонх үүсгэх онцлог"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Дэлгэцийг хуваах"</string>
<string name="more_button_text" msgid="3655388105592893530">"Бусад"</string>
<string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Аспектын харьцааг өөрчлөх"</string>
<string name="close_text" msgid="4986518933445178928">"Хаах"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Дэлгэцийн цонх үүсгэх онцлог)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Хэмжээг өөрчлөх"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index e10c8d82440d..b7b3fb673d96 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ॲप मेनू इथे आढळू शकतो"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एकाहून अधिक ॲप्स एकत्र उघडण्यासाठी डेस्कटॉप विंडोइंग एंटर करा"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ॲप मेनूमधून कधीही फुल स्क्रीनवर परत या"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पहा आणि आणखी बरेच काही करा"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रीन वापरण्यासाठी दुसरे ॲप ड्रॅग करा"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"अ‍ॅपचे हँडल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"अ‍ॅप आयकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुलस्‍क्रीन"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"डेस्कटॉप विंडोइंग"</string>
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन"</string>
<string name="more_button_text" msgid="3655388105592893530">"आणखी"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
<string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोइंग)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदला"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index e18e7ec68640..0896b5ee88cb 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menu apl boleh ditemukan di sini"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Masuki tetingkap desktop untuk membuka berbilang apl serentak"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kembali kepada skrin penuh pada bila-bila masa daripada menu apl"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Seret masuk apl lain untuk menggunakan skrin pisah"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Pengendalian apl"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Tetingkap desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Skrin Pisah"</string>
<string name="more_button_text" msgid="3655388105592893530">"Lagi"</string>
<string name="float_button_text" msgid="9221657008391364581">"Terapung"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Tetingkap desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah saiz"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 334a79799d53..0f336e828f47 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"အက်ပ်မီနူးကို ဤနေရာတွင် တွေ့နိုင်သည်"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"အက်ပ်များစွာကို အတူတကွဖွင့်ရန်အတွက် ဒက်စ်တော့ဝင်းဒိုးမုဒ်သို့ ဝင်ရောက်နိုင်သည်"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"အက်ပ်မီနူးမှ ဖန်သားပြင်အပြည့်သို့ အချိန်မရွေး ပြန်သွားနိုင်သည်"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ကြည့်ပြီး ပိုမိုလုပ်ဆောင်ပါ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းအတွက် အက်ပ်နောက်တစ်ခုကို ဖိဆွဲပါ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"အက်ပ်သုံးသူအမည်"</string>
<string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ဒက်စ်တော့ဝင်းဒိုးမုဒ်"</string>
<string name="split_screen_text" msgid="1396336058129570886">"မျက်နှာပြင် ခွဲ၍ပြသရန်"</string>
<string name="more_button_text" msgid="3655388105592893530">"ပိုပြပါ"</string>
<string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
<string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ဒက်စ်တော့ဝင်းဒိုးမုဒ်)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"အရွယ်ပြင်ရန်"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 7e21b475b2fa..3207614c013f 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Her finner du appmenyen"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Start datamaskin-vindusvisning for å åpne flere apper samtidig"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Du kan gå tilbake til fullskjermmodusen når som helst fra appmenyen"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gjør mer"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dra inn en annen app for å bruke delt skjerm"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Apphåndtak"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Datamaskin-vindusvisning"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Delt skjerm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
<string name="close_text" msgid="4986518933445178928">"Lukk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (datamaskin-vindusvisning)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Endre størrelse"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 976f8378606a..2c7be991dd67 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"एपको मेनु यहाँ भेट्टाउन सकिन्छ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एकभन्दा बढी एपहरू सँगै देखाउन डेस्कटप विन्डोइङ हाल्नुहोस्"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"जुनसुकै बेला एपको मेनुबाट फुल स्क्रिनमा फर्कनुहोस्"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"थप कुरा हेर्नुहोस् र गर्नुहोस्"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रिन मोड प्रयोग गर्न अर्को एप ड्रयाग एन्ड ड्रप गर्नुहोस्"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"एपको ह्यान्डल"</string>
<string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"डेस्कटप विन्डोइङ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रिन"</string>
<string name="more_button_text" msgid="3655388105592893530">"थप"</string>
<string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
<string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटप विन्डोइङ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदल्नुहोस्"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 7178e418a5aa..099f875e0eb9 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Het app-menu vind je hier"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Ga naar de desktopvensterfunctie om meerdere apps tegelijk te openen"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ga wanneer je wilt terug naar volledig scherm vanuit het app-menu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zie en doe meer"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Sleep een andere app hier naartoe om het scherm te splitsen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"App-handgreep"</string>
<string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktopvensterfunctie"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Gesplitst scherm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
<string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktopvensterfunctie)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 7e8929003017..50e3cd6a3022 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ਐਪ ਮੀਨੂ ਇੱਥੇ ਮਿਲ ਸਕਦਾ ਹੈ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ਕਈ ਐਪਾਂ ਨੂੰ ਇਕੱਠੇ ਖੋਲ੍ਹਣ ਲਈ ਡੈਸਕਟਾਪ ਵਿੰਡੋ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ਐਪ ਮੀਨੂ ਤੋਂ ਕਿਸੇ ਵੀ ਸਮੇਂ ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਵਾਪਸ ਜਾਓ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ਦੇਖੋ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਕਰੋ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੇ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਵਿੱਚ ਘਸੀਟੋ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ਐਪ ਹੈਂਡਲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ਡੈਸਕਟਾਪ ਵਿੰਡੋ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ਹੋਰ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
<string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ਡੈਸਕਟਾਪ ਵਿੰਡੋ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ਆਕਾਰ ਬਦਲੋ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 765a2071a037..d5535183551e 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"O menu da app pode ser encontrado aqui"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Entre no modo de janelas de computador para abrir várias apps em conjunto"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Regresse ao ecrã inteiro em qualquer altura a partir do menu da app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arraste outra app para usar o ecrã dividido"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Indicador da app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Janelas de computador"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ecrã dividido"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (janelas de computador)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 68d045fdbe29..286443c69d72 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ai remediat problema?\nAtinge pentru a reveni"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu ai probleme cu camera foto? Atinge pentru a închide."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meniul aplicației poate fi găsit aici"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accesează afișarea în ferestre pe desktop pentru a deschide mai multe aplicații simultan"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revino oricând la ecranul complet din meniul aplicației"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vezi și fă mai multe"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Trage în altă aplicație pentru a folosi ecranul împărțit"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Handle de aplicație"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Ferestre pe desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ecran împărțit"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mai multe"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
<string name="close_text" msgid="4986518933445178928">"Închide"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ferestre pe desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionează"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 8e683b8afb79..472a239ca344 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Здесь вы найдете меню приложения"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Чтобы открыть сразу несколько приложений, перейдите в режим компьютерных окон"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вернуться в полноэкранный режим можно из меню приложения"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Выполняйте несколько задач одновременно"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Перетащите сюда другое приложение, чтобы использовать разделение экрана."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Обозначение приложения"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Режим компьютерных окон"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Разделить экран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Ещё"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
<string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим компьютерных окон)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Изменить размер"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 6d548395bfac..6c91955a425e 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"යෙදුම් මෙනුව මෙතැනින් සොයා ගත හැක"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"බහු යෙදුම් එකවර විවෘත කිරීමට ඩෙස්ක්ටොප් කවුළුවට ඇතුළු වන්න"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"යෙදුම් මෙනුවෙන් ඕනෑම වේලාවක පූර්ණ තිරය වෙත ආපසු යන්න"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"බලන්න සහ තවත් දේ කරන්න"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"බෙදුම් තිරය සඳහා වෙනත් යෙදුමකට අදින්න"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"යෙදුම් හසුරුව"</string>
<string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ඩෙස්ක්ටොප් කවුළුකරණය"</string>
<string name="split_screen_text" msgid="1396336058129570886">"බෙදුම් තිරය"</string>
<string name="more_button_text" msgid="3655388105592893530">"තව"</string>
<string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
<string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ඩෙස්ක්ටොප් කවුළුකරණය)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ප්‍රතිප්‍රමාණය කරන්න"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index c04b03873dc7..08404d016789 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ponuku aplikácie nájdete tu"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Aktivujte windowing na pracovnej ploche a otvorte viac aplikácií naraz"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Z ponuky aplikácie sa môžete kedykoľvek vrátiť na celú obrazovku"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zobrazte si a zvládnite toho viac"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Rozdelenú obrazovku môžete použiť presunutím do inej aplikácie"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Rukoväť aplikácie"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Windowing na pracovnej ploche"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Rozdelená obrazovka"</string>
<string name="more_button_text" msgid="3655388105592893530">"Viac"</string>
<string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
<string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing na pracovnej ploche)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmeniť veľkosť"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 22d7bfe978cc..deed0e0fe27a 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meni aplikacije najdete tukaj"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Preklopite v namizni način prikaza več oken hkrati, če želite odpreti več aplikacij hkrati"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"V meniju aplikacije se lahko kadar koli vrnete v celozaslonski način"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Oglejte si in naredite več"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Za razdeljeni zaslon povlecite sem še eno aplikacijo."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Namizni način prikaza več oken hkrati"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Razdeljen zaslon"</string>
<string name="more_button_text" msgid="3655388105592893530">"Več"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
<string name="close_text" msgid="4986518933445178928">"Zapri"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (namizni način prikaza več oken hkrati)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 9330ec3edde5..c6b8c6da56c2 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menyja e aplikacioneve mund të gjendet këtu"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Kalo te ndërfaqja me dritare në desktop për të hapur disa aplikacione së bashku"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kthehu tek ekrani i plotë në çdo kohë nga menyja e aplikacioneve"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Shiko dhe bëj më shumë"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Zvarrite në një aplikacion tjetër për ekranin e ndarë"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Ndërfaqja me dritare në desktop"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string>
<string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ndërfaqja me dritare në desktop)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ndrysho përmasat"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 5bdad159b146..3fe25f9d3d9e 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Мени апликације можете да пронађете овде"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Уђите у прозорски приказ за рачунаре да бисте истовремено отворили више апликација"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вратите се на цео екран било када из менија апликације"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Видите и урадите више"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Превуците другу апликацију да бисте користили подељени екран"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Идентификатор апликације"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Прозорски приказ за рачунаре"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Још"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени размеру"</string>
<string name="close_text" msgid="4986518933445178928">"Затворите"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (прозорски приказ за рачунаре)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Прилагоди"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 40a0a5aa6288..404bdaf6294d 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Appmenyn finns här"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Använd fönsterstapling för att öppna flera appar samtidigt"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Återgå till helskärm när som helst från appmenyn"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se och gör mer"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dra till en annan app för att dela upp skärmen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Apphandtag"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Fönsterstapling"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Delad skärm"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
<string name="float_button_text" msgid="9221657008391364581">"Svävande"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
<string name="close_text" msgid="4986518933445178928">"Stäng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fönsterstapling)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 20429e17d0d6..3bd7988874b8 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Unaweza kupata menyu ya programu hapa"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Tumia hali ya kupanga madirisha ya kompyuta ya mezani ili ufungue programu nyingi pamoja"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Rudi kwenye skrini nzima wakati wowote ukitumia menyu ya programu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Angalia na ufanye zaidi"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Buruta katika programu nyingine ili utumie skrini iliyogawanywa"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Utambulisho wa programu"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Kupanga madirisha ya kompyuta ya mezani"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Gawa Skrini"</string>
<string name="more_button_text" msgid="3655388105592893530">"Zaidi"</string>
<string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
<string name="close_text" msgid="4986518933445178928">"Funga"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Kupanga madirisha ya kompyuta ya mezani)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Badilisha ukubwa"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 74ecfdcf73a9..12780dfd1747 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ஆப்ஸ் மெனுவை இங்கே பார்க்கலாம்"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"பல ஆப்ஸை ஒன்றாகத் திறக்க டெஸ்க்டாப் சாளரமாக்குதலுக்குச் செல்லலாம்"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ஆப்ஸ் மெனுவிலிருந்து எப்போது வேண்டுமானாலும் முழுத்திரைக்குத் திரும்பலாம்"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"பலவற்றைப் பார்த்தல் மற்றும் செய்தல்"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"திரைப் பிரிப்புக்கு மற்றொரு ஆப்ஸை இழுக்கலாம்"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ஆப்ஸ் ஹேண்டில்"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"டெஸ்க்டாப் சாளரமாக்குதல்"</string>
<string name="split_screen_text" msgid="1396336058129570886">"திரையைப் பிரிக்கும்"</string>
<string name="more_button_text" msgid="3655388105592893530">"கூடுதல் விருப்பத்தேர்வுகள்"</string>
<string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
<string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (டெஸ்க்டாப் சாளரமாக்குதல்)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"அளவை மாற்று"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index f46c9b628d1a..2044fe70c7c3 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"యాప్ మెనూను ఇక్కడ పొందవచ్చు"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"పలు యాప్‌లను ఒకేసారి తెరవడానికి డెస్క్‌టాప్ వీక్షణకు ఎంటర్ అవ్వండి"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"యాప్ మెనూ నుండి ఏ సమయంలోనైనా ఫుల్ స్క్రీన్‌కు తిరిగి రండి"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"చూసి, మరిన్ని చేయండి"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్‌లోకి లాగండి"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"యాప్ హ్యాండిల్"</string>
<string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"డెస్క్‌టాప్ వీక్షణ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"స్ప్లిట్ స్క్రీన్"</string>
<string name="more_button_text" msgid="3655388105592893530">"మరిన్ని"</string>
<string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
<string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (డెస్క్‌టాప్ వీక్షణ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్‌ను పెంచండి"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"సైజ్ మార్చండి"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index ae6df04c255c..586d655d7901 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Makikita rito ang menu ng app"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Pumunta sa desktop windowing para magbukas ng maraming app nang sabay-sabay"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Bumalik sa full screen anumang oras mula sa menu ng app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Tumingin at gumawa ng higit pa"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Mag-drag ng isa pang app para sa split screen"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Handle ng app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
<string name="more_button_text" msgid="3655388105592893530">"Higit pa"</string>
<string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Isara"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 116740ef93f7..9605acfb9a8b 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Uygulama menüsünü burada bulabilirsiniz"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Birden fazla uygulamayı birlikte açmak için masaüstü pencerelemeye geçin"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Uygulama menüsünden dilediğiniz zaman tam ekrana dönebilirsiniz"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daha fazlasını görün ve yapın"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Bölünmüş ekran için başka bir uygulamayı sürükleyin"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Uygulama tanıtıcısı"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Masaüstü pencereleme"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Daha Fazla"</string>
<string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
<string name="close_text" msgid="4986518933445178928">"Kapat"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (masaüstü pencereleme)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Yeniden boyutlandır"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 635bc4086c0d..9614ce9112f7 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ایپ کا مینو یہاں پایا جا سکتا ہے"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"متعدد ایپس کو ایک ساتھ کھولنے کے لیے ڈیسک ٹاپ ونڈوئنگ میں داخل ہوں"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ایپ مینو سے کسی بھی وقت فُل اسکرین پر واپس جائیں"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"دیکھیں اور بہت کچھ کریں"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"اسپلٹ اسکرین کے ليے دوسری ایپ میں گھسیٹیں"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ایپ ہینڈل"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ڈیسک ٹاپ ونڈوئنگ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"اسپلٹ اسکرین"</string>
<string name="more_button_text" msgid="3655388105592893530">"مزید"</string>
<string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
<string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ڈیسک ٹاپ ونڈوئنگ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"سائز تبدیل کریں"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 6ce2bd859bea..6025467ea44b 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ilova menyusi shu yerda chiqadi"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Bir nechta ilovani birga ochish uchun oynalarni desktop rejimida chiqarish"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ilova menyusi orqali istalganda butun ekranga qaytish mumkin"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Yana boshqa amallar"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Ekranni ikkiga ajratish uchun boshqa ilovani bu yerga torting"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ilova identifikatori"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Desktop rejimidagi oynalar"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Ekranni ikkiga ajratish"</string>
<string name="more_button_text" msgid="3655388105592893530">"Yana"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
<string name="close_text" msgid="4986518933445178928">"Yopish"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop rejimidagi oynalar)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
<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>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 67f80c142ea3..4c394b2aec46 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Bạn có thể tìm thấy trình đơn ứng dụng tại đây"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Chuyển sang chế độ cửa sổ trên máy tính để mở nhiều ứng dụng cùng lúc"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Trở về chế độ toàn màn hình bất cứ lúc nào từ trình đơn ứng dụng"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Xem và làm được nhiều việc hơn"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Kéo một ứng dụng khác vào để chia đôi màn hình"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Cửa sổ trên máy tính"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string>
<string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string>
<string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
<string name="close_text" msgid="4986518933445178928">"Đóng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Chế độ cửa sổ trên máy tính)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Đổi kích thước"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 74e6b5c1e491..fda5c744eccf 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可在這裡找到應用程式選單"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你可隨時從應用程式選單返回全螢幕"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖入另一個應用程式即可分割螢幕"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"電腦分割視窗"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 575b217229bd..e83c647b59bb 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可以在這裡查看應用程式選單"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你隨時可以從應用程式選單返回全螢幕模式"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖進另一個應用程式即可使用分割畫面模式"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"應用程式控制代碼"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"電腦分割視窗"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分割畫面"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 30403cd21862..4d658f291e02 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Imenyu ye-app ingatholakala lapha"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Faka ukwenziwa kwamawindi amaningi kwedeskithophu ukuze uvule ama-app amaningi ndawonye"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Buyela esikrinini esigcwele noma nini ukusuka kumenyu ye-app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Bona futhi wenze okuningi"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Hudula kwenye i-app mayelana nokuhlukanisa isikrini"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Inkomba ye-App"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Ukwenziwa kwamawindi amaningi kwedeskithophu"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Hlukanisa isikrini"</string>
<string name="more_button_text" msgid="3655388105592893530">"Okwengeziwe"</string>
<string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string>
@@ -136,8 +134,7 @@
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
<string name="close_text" msgid="4986518933445178928">"Vala"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Ukwenziwa kwamawindi amaningi kwedeskithophu)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Shintsha usayizi"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index e1bf6638a9b2..e68680219349 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -294,6 +294,8 @@
<dimen name="bubble_bar_expanded_view_drop_target_padding_top">60dp</dimen>
<dimen name="bubble_bar_expanded_view_drop_target_padding_bottom">24dp</dimen>
<dimen name="bubble_bar_expanded_view_drop_target_padding_horizontal">48dp</dimen>
+ <dimen name="bubble_bar_drop_target_width">84dp</dimen>
+ <dimen name="bubble_bar_drop_target_height">48dp</dimen>
<!-- Width of the box around bottom center of the screen where drag only leads to dismiss -->
<dimen name="bubble_bar_dismiss_zone_width">192dp</dimen>
<!-- Height of the box around bottom center of the screen where drag only leads to dismiss -->
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
index 25b9f8ccc6ae..f68afea92850 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.shared;
import static android.app.WindowConfiguration.windowingModeToString;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.view.Display.INVALID_DISPLAY;
import android.annotation.IntDef;
import android.app.ActivityManager.RecentTaskInfo;
@@ -65,6 +66,11 @@ public class GroupedTaskInfo implements Parcelable {
private final int mDeskId;
/**
+ * The ID of the display that desk with [mDeskId] is in.
+ */
+ private final int mDeskDisplayId;
+
+ /**
* The type of this particular task info, can be one of TYPE_FULLSCREEN, TYPE_SPLIT or
* TYPE_DESK.
*/
@@ -109,17 +115,19 @@ public class GroupedTaskInfo implements Parcelable {
* Create new for a stack of fullscreen tasks
*/
public static GroupedTaskInfo forFullscreenTasks(@NonNull TaskInfo task) {
- return new GroupedTaskInfo(/* deskId = */ -1, List.of(task), null, TYPE_FULLSCREEN,
- /* minimizedFreeformTaskIds = */ null);
+ return new GroupedTaskInfo(/* deskId = */ -1, /* displayId = */ INVALID_DISPLAY,
+ List.of(task), null,
+ TYPE_FULLSCREEN, /* minimizedFreeformTaskIds = */ null);
}
/**
* Create new for a pair of tasks in split screen
*/
public static GroupedTaskInfo forSplitTasks(@NonNull TaskInfo task1,
- @NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
- return new GroupedTaskInfo(/* deskId = */ -1, List.of(task1, task2), splitBounds,
- TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
+ @NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
+ return new GroupedTaskInfo(/* deskId = */ -1, /* displayId = */ INVALID_DISPLAY,
+ List.of(task1, task2),
+ splitBounds, TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
}
/**
@@ -127,9 +135,11 @@ public class GroupedTaskInfo implements Parcelable {
*/
public static GroupedTaskInfo forDeskTasks(
int deskId,
+ int deskDisplayId,
@NonNull List<TaskInfo> tasks,
@NonNull Set<Integer> minimizedFreeformTaskIds) {
- return new GroupedTaskInfo(deskId, tasks, /* splitBounds = */ null, TYPE_DESK,
+ return new GroupedTaskInfo(deskId, deskDisplayId, tasks, /* splitBounds = */ null,
+ TYPE_DESK,
minimizedFreeformTaskIds.stream().mapToInt(i -> i).toArray());
}
@@ -149,11 +159,13 @@ public class GroupedTaskInfo implements Parcelable {
private GroupedTaskInfo(
int deskId,
+ int deskDisplayId,
@NonNull List<TaskInfo> tasks,
@Nullable SplitBounds splitBounds,
@GroupType int type,
@Nullable int[] minimizedFreeformTaskIds) {
mDeskId = deskId;
+ mDeskDisplayId = deskDisplayId;
mTasks = tasks;
mGroupedTasks = null;
mSplitBounds = splitBounds;
@@ -164,6 +176,7 @@ public class GroupedTaskInfo implements Parcelable {
private GroupedTaskInfo(@NonNull List<GroupedTaskInfo> groupedTasks) {
mDeskId = -1;
+ mDeskDisplayId = INVALID_DISPLAY;
mTasks = null;
mGroupedTasks = groupedTasks;
mSplitBounds = null;
@@ -185,6 +198,7 @@ public class GroupedTaskInfo implements Parcelable {
protected GroupedTaskInfo(@NonNull Parcel parcel) {
mDeskId = parcel.readInt();
+ mDeskDisplayId = parcel.readInt();
mTasks = new ArrayList();
final int numTasks = parcel.readInt();
for (int i = 0; i < numTasks; i++) {
@@ -295,6 +309,16 @@ public class GroupedTaskInfo implements Parcelable {
}
/**
+ * Returns the ID of the display that hosts the desk represented by [mDeskId].
+ */
+ public int getDeskDisplayId() {
+ if (mType != TYPE_DESK) {
+ throw new IllegalStateException("No display ID for non desktop task");
+ }
+ return mDeskDisplayId;
+ }
+
+ /**
* Get type of this recents entry. One of {@link GroupType}.
* Note: This is deprecated, callers should use `isBaseType()` and not make assumptions about
* specific group types
@@ -323,6 +347,7 @@ public class GroupedTaskInfo implements Parcelable {
}
GroupedTaskInfo other = (GroupedTaskInfo) obj;
return mDeskId == other.mDeskId
+ && mDeskDisplayId == other.mDeskDisplayId
&& mType == other.mType
&& Objects.equals(mTasks, other.mTasks)
&& Objects.equals(mGroupedTasks, other.mGroupedTasks)
@@ -332,7 +357,7 @@ public class GroupedTaskInfo implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mDeskId, mType, mTasks, mGroupedTasks, mSplitBounds,
+ return Objects.hash(mDeskId, mDeskDisplayId, mType, mTasks, mGroupedTasks, mSplitBounds,
Arrays.hashCode(mMinimizedTaskIds));
}
@@ -345,6 +370,7 @@ public class GroupedTaskInfo implements Parcelable {
.collect(Collectors.joining(",\n\t", "[\n\t", "\n]")));
} else {
taskString.append("Desk ID= ").append(mDeskId).append(", ");
+ taskString.append("Desk Display ID=").append(mDeskDisplayId).append(", ");
taskString.append("Tasks=" + mTasks.stream()
.map(taskInfo -> getTaskInfoDumpString(taskInfo))
.collect(Collectors.joining(", ", "[", "]")));
@@ -377,6 +403,7 @@ public class GroupedTaskInfo implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mDeskId);
+ parcel.writeInt(mDeskDisplayId);
// We don't use the parcel list methods because we want to only write the TaskInfo state
// and not the subclasses (Recents/RunningTaskInfo) whose fields are all deprecated
final int tasksSize = mTasks != null ? mTasks.size() : 0;
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt
index 9bee11a92430..84e0fbe96de2 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt
@@ -26,4 +26,9 @@ interface BubbleDropTargetBoundsProvider {
* Get bubble bar expanded view visual drop target bounds on screen
*/
fun getBubbleBarExpandedViewDropTargetBounds(onLeft: Boolean): Rect
+
+ /**
+ * Get the bar visual drop target bounds on screen
+ */
+ fun getBarDropTargetBounds(onLeft: Boolean): Rect
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 7f8cfaeb9c03..5d59af940da0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -332,7 +332,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
@Override
public void onThresholdCrossed() {
- BackAnimationController.this.onThresholdCrossed();
+ if (predictiveBackDelayWmTransition()) {
+ mShellExecutor.execute(BackAnimationController.this::onThresholdCrossed);
+ } else {
+ BackAnimationController.this.onThresholdCrossed();
+ }
}
@Override
@@ -448,7 +452,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
final boolean shouldDispatchToAnimator = shouldDispatchToAnimator();
if (!shouldDispatchToAnimator && mActiveCallback != null) {
mCurrentTracker.updateStartLocation();
- tryDispatchOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent());
+ tryDispatchOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent(null));
if (mBackNavigationInfo != null && !isAppProgressGenerationAllowed()) {
tryPilferPointers();
}
@@ -604,7 +608,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
// App is handling back animation. Cancel system animation latency tracking.
cancelLatencyTracking();
- tryDispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent());
+ tryDispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null));
if (!isAppProgressGenerationAllowed()) {
tryPilferPointers();
}
@@ -1041,7 +1045,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
() -> mShellExecutor.execute(this::onBackAnimationFinished));
if (mApps.length >= 1) {
- BackMotionEvent startEvent = mCurrentTracker.createStartEvent();
+ BackMotionEvent startEvent = mCurrentTracker.createStartEvent(mApps[0]);
dispatchOnBackStarted(mActiveCallback, startEvent);
if (startEvent.getSwipeEdge() == EDGE_NONE) {
// TODO(b/373544911): onBackStarted is dispatched here so that
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 03d6b0a8075d..0b45b086e13c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -106,6 +106,8 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider {
private int mBarExpViewDropTargetPaddingTop;
private int mBarExpViewDropTargetPaddingBottom;
private int mBarExpViewDropTargetPaddingHorizontal;
+ private int mBarDropTargetWidth;
+ private int mBarDropTargetHeight;
private PointF mRestingStackPosition;
@@ -181,6 +183,8 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider {
R.dimen.bubble_bar_expanded_view_drop_target_padding_bottom);
mBarExpViewDropTargetPaddingHorizontal = res.getDimensionPixelSize(
R.dimen.bubble_bar_expanded_view_drop_target_padding_horizontal);
+ mBarDropTargetWidth = res.getDimensionPixelSize(R.dimen.bubble_bar_drop_target_width);
+ mBarDropTargetHeight = res.getDimensionPixelSize(R.dimen.bubble_bar_drop_target_height);
if (mShowingInBubbleBar) {
mExpandedViewLargeScreenWidth = mExpandedViewBubbleBarWidth;
@@ -1003,4 +1007,20 @@ public class BubblePositioner implements BubbleDropTargetBoundsProvider {
);
return bounds;
}
+
+ @NonNull
+ @Override
+ public Rect getBarDropTargetBounds(boolean onLeft) {
+ Rect bounds = getBubbleBarExpandedViewDropTargetBounds(onLeft);
+ bounds.top = getBubbleBarTopOnScreen();
+ bounds.bottom = bounds.top + mBarDropTargetHeight;
+ if (onLeft) {
+ // Keep the left edge from expanded view
+ bounds.right = bounds.left + mBarDropTargetWidth;
+ } else {
+ // Keep the right edge from expanded view
+ bounds.left = bounds.right - mBarDropTargetWidth;
+ }
+ return bounds;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
index 728975e8ef9f..6f7d7a486453 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
@@ -649,7 +649,7 @@ public class BubbleTransitions {
@Override
public void continueCollapse() {
mBubble.cleanupTaskView();
- if (mTaskLeash == null || !mTaskLeash.isValid()) return;
+ if (mTaskLeash == null || !mTaskLeash.isValid() || !mRootLeash.isValid()) return;
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.reparent(mTaskLeash, mRootLeash);
t.apply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index 9d4f904e55d0..35435569d8b1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -203,7 +203,11 @@ class BubbleBarExpandedViewDragController(
draggedObject: MagnetizedObject<*>,
) {
dragListener.onReleased(inDismiss = true)
- pinController.onDragEnd()
+ if (dropTargetManager != null) {
+ dropTargetManager.onDragEnded()
+ } else {
+ pinController.onDragEnd()
+ }
dismissView.hide()
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 3997412ab459..2cc9387bd1e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -147,15 +147,23 @@ public class BubbleBarLayerView extends FrameLayout
Log.w(TAG, "dropped invalid bubble: " + mExpandedBubble);
return;
}
+
+ final boolean isBubbleLeft = zone instanceof DragZone.Bubble.Left;
+ final boolean isBubbleRight = zone instanceof DragZone.Bubble.Right;
+ if (!isBubbleLeft && !isBubbleRight) {
+ // If we didn't finish the "change" animation make sure to animate
+ // it back to the right spot
+ locationChangeListener.onChange(mInitialLocation);
+ }
if (zone instanceof DragZone.FullScreen) {
((Bubble) mExpandedBubble).getTaskView().moveToFullscreen();
// Make sure location change listener is updated with the initial
// location -- even if we "switched sides" during the drag, since
// we've ended up in fullscreen, the location shouldn't change.
locationChangeListener.onRelease(mInitialLocation);
- } else if (zone instanceof DragZone.Bubble.Left) {
+ } else if (isBubbleLeft) {
locationChangeListener.onRelease(BubbleBarLocation.LEFT);
- } else if (zone instanceof DragZone.Bubble.Right) {
+ } else if (isBubbleRight) {
locationChangeListener.onRelease(BubbleBarLocation.RIGHT);
}
}
@@ -189,7 +197,7 @@ public class BubbleBarLayerView extends FrameLayout
@NonNull
@Override
public SplitScreenMode getSplitScreenMode() {
- return SplitScreenMode.NONE;
+ return SplitScreenMode.UNSUPPORTED;
}
},
new DragZoneFactory.DesktopWindowModeChecker() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
index 04e8d8dee520..5d603d6c087d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
@@ -221,8 +221,11 @@ public class PipBoundsAlgorithm {
+ " than destination(%s)", sourceRectHint, destinationBounds);
return false;
}
- if (!PictureInPictureParams.isSameAspectRatio(sourceRectHint,
- new Rational(destinationBounds.width(), destinationBounds.height()))) {
+ // We use the aspect ratio of source rect hint to check against destination bounds
+ // here to avoid upscaling error.
+ final Rational srcAspectRatio = new Rational(
+ sourceRectHint.width(), sourceRectHint.height());
+ if (!PictureInPictureParams.isSameAspectRatio(destinationBounds, srcAspectRatio)) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"isSourceRectHintValidForEnterPip=false, hint(%s) does not match"
+ " destination(%s) aspect ratio", sourceRectHint, destinationBounds);
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 0920f274f51d..093e8ef8bc0e 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
@@ -287,8 +287,8 @@ class DesktopTasksController(
DeskRecreationFactory { deskUserId, destinationDisplayId, deskId ->
if (deskUserId != userId) {
// TODO: b/400984250 - add multi-user support for multi-desk restoration.
- logW("Tried to recreated desk of another user.")
- deskId
+ logW("Tried to re-create desk of another user.")
+ null
} else {
desksOrganizer.createDesk(destinationDisplayId)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 95cc1e68ac11..f382632ff790 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -46,6 +46,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj;
import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.util.LatencyTracker;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
import com.android.wm.shell.transition.Transitions;
@@ -68,6 +69,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
private final Context mContext;
private final Transitions mTransitions;
private final InteractionJankMonitor mInteractionJankMonitor;
+ private final LatencyTracker mLatencyTracker;
@ShellMainThread
private final Handler mHandler;
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
@@ -95,6 +97,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
mTransactionSupplier = supplier;
mContext = context;
mInteractionJankMonitor = interactionJankMonitor;
+ mLatencyTracker = LatencyTracker.getInstance(mContext);
mHandler = handler;
}
@@ -109,6 +112,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
public IBinder startTransition(@NonNull DesktopModeTransitionSource transitionSource,
@NonNull WindowContainerTransaction wct, Point position,
Function0<Unit> onAnimationEndCallback) {
+ mLatencyTracker.onActionStart(LatencyTracker.ACTION_DESKTOP_MODE_EXIT_MODE);
mPosition = position;
mOnAnimationFinishedCallback = onAnimationEndCallback;
final IBinder token = mTransitions.startTransition(getExitTransitionType(transitionSource),
@@ -141,6 +145,11 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
mPendingTransitionTokens.remove(transition);
+
+ if (transitionHandled) {
+ mLatencyTracker.onActionEnd(LatencyTracker.ACTION_DESKTOP_MODE_EXIT_MODE);
+ }
+
return transitionHandled;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
index 23562388b3e5..5e4122ba14ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainer.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.desktopmode
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
import android.animation.RectEvaluator
import android.animation.ValueAnimator
import android.app.ActivityManager
@@ -32,6 +33,8 @@ import android.view.View
import android.view.WindowManager
import android.view.WindowlessWindowManager
import android.view.animation.DecelerateInterpolator
+import android.widget.FrameLayout
+import androidx.core.animation.doOnEnd
import com.android.internal.annotations.VisibleForTesting
import com.android.window.flags.Flags
import com.android.wm.shell.R
@@ -42,6 +45,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType
import com.android.wm.shell.shared.annotations.ShellDesktopThread
import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
import com.android.wm.shell.windowdecor.WindowDecoration.SurfaceControlViewHostFactory
import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
@@ -64,6 +68,8 @@ constructor(
private val snapEventHandler: SnapEventHandler,
) {
@VisibleForTesting var indicatorView: View? = null
+ // Optional extra indicator showing the outline of the bubble bar
+ private var barIndicatorView: View? = null
private var indicatorViewHost: SurfaceControlViewHost? = null
// Below variables and the SyncTransactionQueue are the only variables that should
// be accessed from shell main thread. Everything else should be used exclusively
@@ -93,7 +99,12 @@ constructor(
screenWidth = metrics.widthPixels
screenHeight = metrics.heightPixels
}
- indicatorView = View(context)
+ indicatorView =
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ FrameLayout(context)
+ } else {
+ View(context)
+ }
val leash =
indicatorBuilder
.setName("Desktop Mode Visual Indicator")
@@ -183,23 +194,50 @@ constructor(
)
} else {
val animStartType = IndicatorType.valueOf(currentType.name)
- val animator =
- indicatorView?.let {
- VisualIndicatorAnimator.animateIndicatorType(
- it,
- layout,
- animStartType,
- newType,
- bubbleBoundsProvider,
- taskInfo.displayId,
- snapEventHandler,
- )
- } ?: return@execute
+ val indicator = indicatorView ?: return@execute
+ var animator: Animator =
+ VisualIndicatorAnimator.animateIndicatorType(
+ indicator,
+ layout,
+ animStartType,
+ newType,
+ bubbleBoundsProvider,
+ taskInfo.displayId,
+ snapEventHandler,
+ )
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ if (currentType.isBubbleType() || newType.isBubbleType()) {
+ animator = addBarIndicatorAnimation(animator, currentType, newType)
+ }
+ }
animator.start()
}
}
}
+ private fun addBarIndicatorAnimation(
+ visualIndicatorAnimator: Animator,
+ currentType: IndicatorType,
+ newType: IndicatorType,
+ ): Animator {
+ if (newType.isBubbleType()) {
+ getOrCreateBubbleBarIndicator(newType)?.let { bar ->
+ return AnimatorSet().apply {
+ playTogether(visualIndicatorAnimator, fadeBarIndicatorIn(bar))
+ }
+ }
+ }
+ if (currentType.isBubbleType()) {
+ barIndicatorView?.let { bar ->
+ barIndicatorView = null
+ return AnimatorSet().apply {
+ playTogether(visualIndicatorAnimator, fadeBarIndicatorOut(bar))
+ }
+ }
+ }
+ return visualIndicatorAnimator
+ }
+
/**
* Fade indicator in as provided type.
*
@@ -223,17 +261,20 @@ constructor(
snapEventHandler: SnapEventHandler,
) {
desktopExecutor.assertCurrentThread()
- indicatorView?.let {
- it.setBackgroundResource(R.drawable.desktop_windowing_transition_background)
- val animator =
+ indicatorView?.let { indicator ->
+ indicator.setBackgroundResource(R.drawable.desktop_windowing_transition_background)
+ var animator: Animator =
VisualIndicatorAnimator.fadeBoundsIn(
- it,
+ indicator,
type,
layout,
bubbleBoundsProvider,
displayId,
snapEventHandler,
)
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ animator = addBarIndicatorAnimation(animator, IndicatorType.NO_INDICATOR, type)
+ }
animator.start()
}
}
@@ -259,7 +300,7 @@ constructor(
desktopExecutor.execute {
indicatorView?.let {
val animStartType = IndicatorType.valueOf(currentType.name)
- val animator =
+ var animator: Animator =
VisualIndicatorAnimator.fadeBoundsOut(
it,
animStartType,
@@ -268,6 +309,10 @@ constructor(
displayId,
snapEventHandler,
)
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ animator =
+ addBarIndicatorAnimation(animator, currentType, IndicatorType.NO_INDICATOR)
+ }
animator.addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
@@ -302,6 +347,38 @@ constructor(
isReleased = true
}
+ private fun getOrCreateBubbleBarIndicator(type: IndicatorType): View? {
+ val container = indicatorView as? FrameLayout ?: return null
+ val onLeft = type == IndicatorType.TO_BUBBLE_LEFT_INDICATOR
+ val bounds = bubbleBoundsProvider?.getBarDropTargetBounds(onLeft) ?: return null
+ val lp = FrameLayout.LayoutParams(bounds.width(), bounds.height())
+ lp.leftMargin = bounds.left
+ lp.topMargin = bounds.top
+ if (barIndicatorView == null) {
+ val indicator = View(container.context)
+ indicator.setBackgroundResource(R.drawable.desktop_windowing_transition_background)
+ container.addView(indicator, lp)
+ barIndicatorView = indicator
+ } else {
+ barIndicatorView?.layoutParams = lp
+ }
+ return barIndicatorView
+ }
+
+ private fun fadeBarIndicatorIn(barIndicator: View): Animator {
+ // Use layout bounds as the end bounds in case the view has not been laid out yet
+ val lp = barIndicator.layoutParams
+ val endBounds = Rect(0, 0, lp.width, lp.height)
+ return VisualIndicatorAnimator.fadeBoundsIn(barIndicator, endBounds)
+ }
+
+ private fun fadeBarIndicatorOut(barIndicator: View): Animator {
+ val startBounds = Rect(0, 0, barIndicator.width, barIndicator.height)
+ val barAnimator = VisualIndicatorAnimator.fadeBoundsOut(barIndicator, startBounds)
+ barAnimator.doOnEnd { (indicatorView as? FrameLayout)?.removeView(barIndicator) }
+ return barAnimator
+ }
+
/**
* Animator for Desktop Mode transitions which supports bounds and alpha animation. Functions
* should only be called from the desktop executor.
@@ -383,9 +460,13 @@ constructor(
displayId,
snapEventHandler,
)
+ return fadeBoundsIn(view, endBounds)
+ }
+
+ @ShellDesktopThread
+ fun fadeBoundsIn(view: View, endBounds: Rect): VisualIndicatorAnimator {
val startBounds = getMinBounds(endBounds)
view.background.bounds = startBounds
-
val animator = VisualIndicatorAnimator(view, startBounds, endBounds)
animator.interpolator = DecelerateInterpolator()
setupIndicatorAnimation(animator, AlphaAnimType.ALPHA_FADE_IN_ANIM)
@@ -409,6 +490,11 @@ constructor(
displayId,
snapEventHandler,
)
+ return fadeBoundsOut(view, startBounds)
+ }
+
+ @ShellDesktopThread
+ fun fadeBoundsOut(view: View, startBounds: Rect): VisualIndicatorAnimator {
val endBounds = getMinBounds(startBounds)
view.background.bounds = startBounds
val animator = VisualIndicatorAnimator(view, startBounds, endBounds)
@@ -571,4 +657,9 @@ constructor(
}
}
}
+
+ private fun IndicatorType.isBubbleType(): Boolean {
+ return this == IndicatorType.TO_BUBBLE_LEFT_INDICATOR ||
+ this == IndicatorType.TO_BUBBLE_RIGHT_INDICATOR
+ }
}
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 8191181cac11..a2dd5dbc8709 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
@@ -21,7 +21,7 @@ import kotlinx.coroutines.flow.StateFlow
/** Interface for initializing the [DesktopUserRepositories]. */
interface DesktopRepositoryInitializer {
- /** A factory used to recreate a desk from persistence. */
+ /** A factory used to re-create a desk from persistence. */
var deskRecreationFactory: DeskRecreationFactory
/** A flow that emits true when the repository has been initialized. */
@@ -30,9 +30,11 @@ interface DesktopRepositoryInitializer {
/** Initialize the user repositories from a persistent data store. */
fun initialize(userRepositories: DesktopUserRepositories)
- /** A factory for recreating desks. */
+ /** A factory for re-creating desks. */
fun interface DeskRecreationFactory {
- /** Recreates a restored desk and returns the new desk id. */
- suspend fun recreateDesk(userId: Int, destinationDisplayId: Int, deskId: Int): Int
+ /**
+ * Re-creates a restored desk and returns the new desk id, or null if re-creation failed.
+ */
+ suspend fun recreateDesk(userId: Int, destinationDisplayId: Int, deskId: Int): Int?
}
}
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 5ed0b1d1616f..3ee48072ee86 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
@@ -69,7 +69,7 @@ class DesktopRepositoryInitializerImpl(
desksToRestore.map { it.desktopId },
userId,
)
- desksToRestore.forEach { persistentDesktop ->
+ for (persistentDesktop in desksToRestore) {
val maxTasks = getTaskLimit(persistentDesktop)
val displayId = persistentDesktop.displayId
val deskId = persistentDesktop.desktopId
@@ -81,17 +81,29 @@ class DesktopRepositoryInitializerImpl(
destinationDisplayId = newDisplayId,
deskId = deskId,
)
- logV(
- "Recreated desk=%d in display=%d using new deskId=%d and displayId=%d",
- deskId,
- displayId,
- newDeskId,
- newDisplayId,
- )
- if (newDeskId != deskId || newDisplayId != displayId) {
+ if (newDeskId != null) {
+ logV(
+ "Re-created desk=%d in display=%d using new" +
+ " deskId=%d and displayId=%d",
+ deskId,
+ displayId,
+ newDeskId,
+ newDisplayId,
+ )
+ }
+ if (newDeskId == null || newDeskId != deskId || newDisplayId != displayId) {
logV("Removing obsolete desk from persistence under deskId=%d", deskId)
persistentRepository.removeDesktop(userId, deskId)
}
+ if (newDeskId == null) {
+ logW(
+ "Could not re-create desk=%d from display=%d in displayId=%d",
+ deskId,
+ displayId,
+ newDisplayId,
+ )
+ continue
+ }
// TODO: b/393961770 - [DesktopRepository] doesn't save desks to the
// persistent repository until a task is added to them. Update it so that
@@ -177,6 +189,10 @@ class DesktopRepositoryInitializerImpl(
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
}
+ private fun logW(msg: String, vararg arguments: Any?) {
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
/** A default implementation of [DeskRecreationFactory] that reuses the desk id. */
private class DefaultDeskRecreationFactory : DeskRecreationFactory {
override suspend fun recreateDesk(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 4e341ac9b7eb..0e974ef9083b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -31,6 +31,8 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Debug;
+import android.util.Log;
import android.view.SurfaceControl;
import android.window.DesktopExperienceFlags;
import android.window.DisplayAreaInfo;
@@ -369,7 +371,13 @@ public class PipController implements ConfigurationChangeListener,
mPipBoundsAlgorithm.applySnapFraction(toBounds, snapFraction);
mPipBoundsState.setBounds(toBounds);
}
- t.setBounds(mPipTransitionState.getPipTaskToken(), mPipBoundsState.getBounds());
+ if (mPipTransitionState.getPipTaskToken() == null) {
+ Log.wtf(TAG, "PipController.onDisplayChange no PiP task token"
+ + " state=" + mPipTransitionState.getState()
+ + " callers=\n" + Debug.getCallers(4, " "));
+ } else {
+ t.setBounds(mPipTransitionState.getPipTaskToken(), mPipBoundsState.getBounds());
+ }
// Update the size spec in PipBoundsState afterwards.
mPipBoundsState.updateMinMaxSize(mPipBoundsState.getAspectRatio());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
index 880e143a0e13..92f36d08a941 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
@@ -43,6 +43,7 @@ import com.android.wm.shell.shared.annotations.ShellMainThread;
import java.util.ArrayList;
import java.util.List;
+import java.util.StringJoiner;
/**
* A Task Listener implementation used only for CUJs and trigger paths that cannot be initiated via
@@ -114,6 +115,17 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener,
// Set the new params but make sure mPictureInPictureParams is not null.
mPictureInPictureParams = params == null
? new PictureInPictureParams.Builder().build() : params;
+ logRemoteActions(mPictureInPictureParams);
+ }
+
+ private void logRemoteActions(@android.annotation.NonNull PictureInPictureParams params) {
+ StringJoiner sj = new StringJoiner("|", "[", "]");
+ if (params.hasSetActions()) {
+ params.getActions().forEach((action) -> sj.add(action.getTitle()));
+ }
+
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "PIP remote actions=%s", sj.toString());
}
/** Add a PipParamsChangedCallback listener. */
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 bb5b5cec1b4a..382fa9640ff9 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
@@ -536,17 +536,20 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
/**
- * Represents a desk whose ID is `mDeskId` and contains the tasks in `mDeskTasks`. Some of these
- * tasks are minimized and their IDs are contained in the `mMinimizedDeskTasks` set.
+ * Represents a desk whose ID is `mDeskId` inside the display with `mDisplayId` and contains
+ * the tasks in `mDeskTasks`. Some of these tasks are minimized and their IDs are contained
+ * in the `mMinimizedDeskTasks` set.
*/
private static class Desk {
final int mDeskId;
+ final int mDisplayId;
boolean mHasVisibleTasks = false;
final ArrayList<TaskInfo> mDeskTasks = new ArrayList<>();
final Set<Integer> mMinimizedDeskTasks = new HashSet<>();
- Desk(int deskId) {
+ Desk(int deskId, int displayId) {
mDeskId = deskId;
+ mDisplayId = displayId;
}
void addTask(TaskInfo taskInfo, boolean isMinimized, boolean isVisible) {
@@ -562,7 +565,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
GroupedTaskInfo createDeskTaskInfo() {
- return GroupedTaskInfo.forDeskTasks(mDeskId, mDeskTasks, mMinimizedDeskTasks);
+ return GroupedTaskInfo.forDeskTasks(mDeskId, mDisplayId, mDeskTasks,
+ mMinimizedDeskTasks);
}
}
@@ -601,7 +605,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
private Desk getOrCreateDesk(int deskId) {
var desk = mTmpDesks.get(deskId);
if (desk == null) {
- desk = new Desk(deskId);
+ desk = new Desk(deskId,
+ mDesktopUserRepositories.get().getCurrent().getDisplayForDesk(deskId));
mTmpDesks.put(deskId, desk);
}
return desk;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index 23dfb41d52c1..cca982142a3a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -153,7 +153,6 @@ public class HomeTransitionObserver implements TransitionObserver,
return;
}
mPendingStartDragTransition = null;
- if (aborted) return;
if (mPendingHomeVisibilityUpdate != null) {
notifyHomeVisibilityChanged(mPendingHomeVisibilityUpdate);
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 5e8c1fe2aa8d..e08ef5883390 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
@@ -49,6 +49,7 @@ import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.WindowContainerTransaction;
@@ -218,11 +219,17 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
relayoutParams.mRunningTaskInfo = taskInfo;
relayoutParams.mLayoutResId = R.layout.caption_window_decor;
relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
- relayoutParams.mShadowRadius = hasGlobalFocus
- ? context.getResources().getDimensionPixelSize(
- R.dimen.freeform_decor_shadow_focused_thickness)
- : context.getResources().getDimensionPixelSize(
- R.dimen.freeform_decor_shadow_unfocused_thickness);
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ relayoutParams.mShadowRadiusId = hasGlobalFocus
+ ? R.dimen.freeform_decor_shadow_focused_thickness
+ : R.dimen.freeform_decor_shadow_unfocused_thickness;
+ } else {
+ 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()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
index 3182745d813e..f6acca95916f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
@@ -27,6 +27,7 @@ import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowInsets;
+import android.window.DesktopModeFlags;
import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
@@ -88,6 +89,9 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
updateRelayoutParams(mRelayoutParams, taskInfo, isCaptionVisible);
relayout(mRelayoutParams, startT, finishT, wct, mRootView, mResult);
+ if (DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
+ setCaptionVisibility(isCaptionVisible);
+ }
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
mBgExecutor.execute(() -> mTaskOrganizer.applyTransaction(wct));
@@ -102,6 +106,15 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
}
}
+ private void setCaptionVisibility(boolean visible) {
+ if (mRootView == null) {
+ return;
+ }
+ final int v = visible ? View.VISIBLE : View.GONE;
+ final View captionView = mRootView.findViewById(getCaptionViewId());
+ captionView.setVisibility(v);
+ }
+
@Override
@NonNull
Rect calculateValidDragArea() {
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 bcf9396ff0c1..ae103895d56b 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
@@ -72,6 +72,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.ImageButton;
+import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.TaskSnapshot;
import android.window.WindowContainerTransaction;
@@ -719,7 +720,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
.getScaledTouchSlop();
final Resources res = mResult.mRootView.getResources();
final DragResizeWindowGeometry newGeometry = new DragResizeWindowGeometry(
- mRelayoutParams.mCornerRadius,
+ DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()
+ ? mResult.mCornerRadius : mRelayoutParams.mCornerRadius,
new Size(mResult.mWidth, mResult.mHeight),
getResizeEdgeHandleSize(res), getResizeHandleEdgeInset(res),
getFineResizeCornerSize(res), getLargeResizeCornerSize(res),
@@ -861,7 +863,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
if (!isAppHandle(mWindowDecorViewHolder)) return;
asAppHandle(mWindowDecorViewHolder).bindData(new AppHandleViewHolder.HandleData(
mTaskInfo, determineHandlePosition(), mResult.mCaptionWidth,
- mResult.mCaptionHeight, isCaptionVisible()
+ mResult.mCaptionHeight, /* showInputLayer= */ isCaptionVisible(),
+ /* isCaptionVisible= */ isCaptionVisible()
));
}
@@ -874,7 +877,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
inFullImmersive,
hasGlobalFocus,
/* maximizeHoverEnabled= */ canOpenMaximizeMenu(
- /* animatingTaskResizeOrReposition= */ false)
+ /* animatingTaskResizeOrReposition= */ false),
+ isCaptionVisible()
));
}
@@ -1072,13 +1076,23 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
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);
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ relayoutParams.mShadowRadiusId = hasGlobalFocus
+ ? R.dimen.freeform_decor_shadow_focused_thickness
+ : R.dimen.freeform_decor_shadow_unfocused_thickness;
+ } else {
+ 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;
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ relayoutParams.mShadowRadiusId = Resources.ID_NULL;
+ } else {
+ relayoutParams.mShadowRadius = INVALID_SHADOW_RADIUS;
+ }
}
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
@@ -1104,8 +1118,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
relayoutParams.mWindowDecorConfig = windowDecorConfig;
if (DesktopModeStatus.useRoundedCorners()) {
- relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
- getCornerRadius(context, relayoutParams.mLayoutResId);
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ relayoutParams.mCornerRadiusId = shouldIgnoreCornerRadius ? Resources.ID_NULL :
+ getCornerRadiusId(relayoutParams.mLayoutResId);
+ } else {
+ relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
+ getCornerRadius(context, relayoutParams.mLayoutResId);
+ }
}
// Set opaque background for all freeform tasks to prevent freeform tasks below
// from being visible if freeform task window above is translucent.
@@ -1113,6 +1132,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
relayoutParams.mShouldSetBackground = DesktopModeStatus.shouldSetBackground(taskInfo);
}
+ @Deprecated
private static int getCornerRadius(@NonNull Context context, int layoutResId) {
if (layoutResId == R.layout.desktop_mode_app_header) {
return loadDimensionPixelSize(context.getResources(),
@@ -1122,6 +1142,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
return INVALID_CORNER_RADIUS;
}
+ private static int getCornerRadiusId(int layoutResId) {
+ if (layoutResId == R.layout.desktop_mode_app_header) {
+ return com.android.wm.shell.shared.R.dimen
+ .desktop_windowing_freeform_rounded_corner_radius;
+ }
+ return Resources.ID_NULL;
+ }
+
/**
* If task has focused window decor, return the caption id of the fullscreen caption size
* resource. Otherwise, return ID_NULL and caption width be set to task width.
@@ -1756,8 +1784,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
disposeResizeVeil();
disposeStatusBarInputLayer();
- mWindowDecorViewHolder.close();
- mWindowDecorViewHolder = null;
+ if (mWindowDecorViewHolder != null) {
+ mWindowDecorViewHolder.close();
+ mWindowDecorViewHolder = null;
+ }
if (canEnterDesktopMode(mContext) && isEducationEnabled()) {
notifyNoCaptionHandle();
}
@@ -1838,7 +1868,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController),
inFullImmersive,
isFocused(),
- /* maximizeHoverEnabled= */ canOpenMaximizeMenu(animatingTaskResizeOrReposition)));
+ /* maximizeHoverEnabled= */ canOpenMaximizeMenu(animatingTaskResizeOrReposition),
+ isCaptionVisible()));
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
index eb324f74ca82..238242792782 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
@@ -278,13 +278,16 @@ class MultiDisplayVeiledResizeTaskPositioner(
currentDisplayLayout,
)
)
-
- multiDisplayDragMoveIndicatorController.onDragEnd(
- desktopWindowDecoration.mTaskInfo.taskId,
- transactionSupplier,
- )
}
+ // Call the MultiDisplayDragMoveIndicatorController to clear any active indicator
+ // surfaces. This is necessary even if the drag ended on the same display, as surfaces
+ // may have been created for other displays during the drag.
+ multiDisplayDragMoveIndicatorController.onDragEnd(
+ desktopWindowDecoration.mTaskInfo.taskId,
+ transactionSupplier,
+ )
+
interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_DRAG_WINDOW)
}
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 91a899c09407..6a9b366dfb97 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
@@ -47,6 +47,8 @@ import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
+import android.window.DesktopExperienceFlags;
+import android.window.DesktopModeFlags;
import android.window.SurfaceSyncGroup;
import android.window.TaskConstants;
import android.window.WindowContainerToken;
@@ -286,6 +288,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
outResult.mCaptionX = (outResult.mWidth - outResult.mCaptionWidth) / 2;
outResult.mCaptionY = 0;
outResult.mCaptionTopPadding = params.mCaptionTopPadding;
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ outResult.mCornerRadius = params.mCornerRadiusId == Resources.ID_NULL
+ ? INVALID_CORNER_RADIUS : loadDimensionPixelSize(resources,
+ params.mCornerRadiusId);
+ outResult.mShadowRadius = params.mShadowRadiusId == Resources.ID_NULL
+ ? INVALID_SHADOW_RADIUS : loadDimensionPixelSize(resources,
+ params.mShadowRadiusId);
+ }
Trace.beginSection("relayout-createViewHostIfNeeded");
createViewHostIfNeeded(mDecorWindowContext, mDisplay);
@@ -497,9 +507,16 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.setPosition(mTaskSurface, taskPosition.x, taskPosition.y);
}
- if (params.mShadowRadius != INVALID_SHADOW_RADIUS) {
- startT.setShadowRadius(mTaskSurface, params.mShadowRadius);
- finishT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ if (outResult.mShadowRadius != INVALID_SHADOW_RADIUS) {
+ startT.setShadowRadius(mTaskSurface, outResult.mShadowRadius);
+ finishT.setShadowRadius(mTaskSurface, outResult.mShadowRadius);
+ }
+ } else {
+ if (params.mShadowRadius != INVALID_SHADOW_RADIUS) {
+ startT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+ finishT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+ }
}
if (params.mSetTaskVisibilityPositionAndCrop) {
@@ -517,9 +534,16 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
startT.unsetColor(mTaskSurface);
}
- if (params.mCornerRadius != INVALID_CORNER_RADIUS) {
- startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
- finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ if (outResult.mCornerRadius != INVALID_CORNER_RADIUS) {
+ startT.setCornerRadius(mTaskSurface, outResult.mCornerRadius);
+ finishT.setCornerRadius(mTaskSurface, outResult.mCornerRadius);
+ }
+ } else {
+ if (params.mCornerRadius != INVALID_CORNER_RADIUS) {
+ startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ }
}
}
@@ -629,7 +653,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
*/
private void updateCaptionVisibility(View rootView, @NonNull RelayoutParams params) {
mIsCaptionVisible = params.mIsCaptionVisible;
- setCaptionVisibility(rootView, mIsCaptionVisible);
+ if (!DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
+ setCaptionVisibility(rootView, mIsCaptionVisible);
+ }
}
void setTaskDragResizer(TaskDragResizer taskDragResizer) {
@@ -824,9 +850,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
@InsetsSource.Flags int mInsetSourceFlags;
final Region mDisplayExclusionRegion = Region.obtain();
+ @Deprecated
int mShadowRadius = INVALID_SHADOW_RADIUS;
+ @Deprecated
int mCornerRadius = INVALID_CORNER_RADIUS;
+ int mShadowRadiusId = Resources.ID_NULL;
+ int mCornerRadiusId = Resources.ID_NULL;
+
int mCaptionTopPadding;
boolean mIsCaptionVisible;
@@ -849,9 +880,13 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mIsInsetSource = true;
mInsetSourceFlags = 0;
mDisplayExclusionRegion.setEmpty();
-
- mShadowRadius = INVALID_SHADOW_RADIUS;
- mCornerRadius = INVALID_SHADOW_RADIUS;
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ mShadowRadiusId = Resources.ID_NULL;
+ mCornerRadiusId = Resources.ID_NULL;
+ } else {
+ mShadowRadius = INVALID_SHADOW_RADIUS;
+ mCornerRadius = INVALID_SHADOW_RADIUS;
+ }
mCaptionTopPadding = 0;
mIsCaptionVisible = false;
@@ -893,6 +928,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
int mWidth;
int mHeight;
T mRootView;
+ int mCornerRadius;
+ int mShadowRadius;
void reset() {
mWidth = 0;
@@ -904,6 +941,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mCaptionTopPadding = 0;
mCustomizableCaptionRegion.setEmpty();
mRootView = null;
+ if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+ mCornerRadius = INVALID_CORNER_RADIUS;
+ mShadowRadius = INVALID_SHADOW_RADIUS;
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleAnimator.kt
new file mode 100644
index 000000000000..f0a85306d177
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleAnimator.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor
+
+import android.animation.ObjectAnimator
+import android.view.View
+import android.view.View.Visibility
+import android.view.animation.PathInterpolator
+import android.widget.ImageButton
+import androidx.core.animation.doOnEnd
+import com.android.wm.shell.shared.animation.Interpolators
+
+/**
+ * Animates the Desktop View's app handle.
+ */
+class AppHandleAnimator(
+ private val appHandleView: View,
+ private val captionHandle: ImageButton,
+) {
+ companion object {
+ // Constants for animating the whole caption
+ private const val APP_HANDLE_ALPHA_FADE_IN_ANIMATION_DURATION_MS: Long = 275L
+ private const val APP_HANDLE_ALPHA_FADE_OUT_ANIMATION_DURATION_MS: Long = 340
+ private val APP_HANDLE_ANIMATION_INTERPOLATOR = PathInterpolator(
+ 0.4f,
+ 0f,
+ 0.2f,
+ 1f
+ )
+
+ // Constants for animating the caption's handle
+ private const val HANDLE_ANIMATION_DURATION: Long = 100
+ private val HANDLE_ANIMATION_INTERPOLATOR = Interpolators.FAST_OUT_SLOW_IN
+ }
+
+ private var animator: ObjectAnimator? = null
+
+ /** Animates the given caption view to the given visibility after a visibility change. */
+ fun animateVisibilityChange(@Visibility visible: Int) {
+ when (visible) {
+ View.VISIBLE -> animateShowAppHandle()
+ else -> animateHideAppHandle()
+ }
+ }
+
+ /** Animate appearance/disappearance of caption's handle. */
+ fun animateCaptionHandleAlpha(startValue: Float, endValue: Float) {
+ cancel()
+ animator = ObjectAnimator.ofFloat(captionHandle, View.ALPHA, startValue, endValue).apply {
+ duration = HANDLE_ANIMATION_DURATION
+ interpolator = HANDLE_ANIMATION_INTERPOLATOR
+ start()
+ }
+ }
+
+ private fun animateShowAppHandle() {
+ cancel()
+ appHandleView.alpha = 0f
+ appHandleView.visibility = View.VISIBLE
+ animator = ObjectAnimator.ofFloat(appHandleView, View.ALPHA, 1f).apply {
+ duration = APP_HANDLE_ALPHA_FADE_IN_ANIMATION_DURATION_MS
+ interpolator = APP_HANDLE_ANIMATION_INTERPOLATOR
+ start()
+ }
+ }
+
+ private fun animateHideAppHandle() {
+ cancel()
+ animator = ObjectAnimator.ofFloat(appHandleView, View.ALPHA, 0f).apply {
+ duration = APP_HANDLE_ALPHA_FADE_OUT_ANIMATION_DURATION_MS
+ interpolator = APP_HANDLE_ANIMATION_INTERPOLATOR
+ doOnEnd {
+ appHandleView.visibility = View.GONE
+ }
+ start()
+ }
+ }
+
+ /**
+ * Cancels any active animations.
+ */
+ fun cancel() {
+ animator?.removeAllListeners()
+ animator?.cancel()
+ animator = null
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 0985587a330e..9d16be59ba34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -15,7 +15,6 @@
*/
package com.android.wm.shell.windowdecor.viewholder
-import android.animation.ObjectAnimator
import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.content.res.ColorStateList
@@ -40,8 +39,8 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
import com.android.internal.policy.SystemBarUtils
import com.android.window.flags.Flags
import com.android.wm.shell.R
-import com.android.wm.shell.shared.animation.Interpolators
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
+import com.android.wm.shell.windowdecor.AppHandleAnimator
import com.android.wm.shell.windowdecor.WindowManagerWrapper
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
@@ -57,22 +56,20 @@ class AppHandleViewHolder(
private val handler: Handler
) : WindowDecorationViewHolder<AppHandleViewHolder.HandleData>(rootView) {
- companion object {
- private const val CAPTION_HANDLE_ANIMATION_DURATION: Long = 100
- }
-
data class HandleData(
val taskInfo: RunningTaskInfo,
val position: Point,
val width: Int,
val height: Int,
- val showInputLayer: Boolean
+ val showInputLayer: Boolean,
+ val isCaptionVisible: Boolean,
) : Data()
private lateinit var taskInfo: RunningTaskInfo
private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption)
private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle)
private val inputManager = context.getSystemService(InputManager::class.java)
+ private val animator: AppHandleAnimator = AppHandleAnimator(rootView, captionHandle)
private var statusBarInputLayerExists = false
// An invisible View that takes up the same coordinates as captionHandle but is layered
@@ -101,7 +98,14 @@ class AppHandleViewHolder(
}
override fun bindData(data: HandleData) {
- bindData(data.taskInfo, data.position, data.width, data.height, data.showInputLayer)
+ bindData(
+ data.taskInfo,
+ data.position,
+ data.width,
+ data.height,
+ data.showInputLayer,
+ data.isCaptionVisible
+ )
}
private fun bindData(
@@ -109,8 +113,10 @@ class AppHandleViewHolder(
position: Point,
width: Int,
height: Int,
- showInputLayer: Boolean
+ showInputLayer: Boolean,
+ isCaptionVisible: Boolean
) {
+ setVisibility(isCaptionVisible)
captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
this.taskInfo = taskInfo
// If handle is not in status bar region(i.e., bottom stage in vertical split),
@@ -131,11 +137,11 @@ class AppHandleViewHolder(
}
override fun onHandleMenuOpened() {
- animateCaptionHandleAlpha(startValue = 1f, endValue = 0f)
+ animator.animateCaptionHandleAlpha(startValue = 1f, endValue = 0f)
}
override fun onHandleMenuClosed() {
- animateCaptionHandleAlpha(startValue = 0f, endValue = 1f)
+ animator.animateCaptionHandleAlpha(startValue = 0f, endValue = 1f)
}
private fun createStatusBarInputLayer(handlePosition: Point,
@@ -239,6 +245,17 @@ class AppHandleViewHolder(
}
}
+ private fun setVisibility(visible: Boolean) {
+ val v = if (visible) View.VISIBLE else View.GONE
+ if (
+ captionView.visibility == v ||
+ !DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()
+ ) {
+ return
+ }
+ animator.animateVisibilityChange(v)
+ }
+
private fun getCaptionHandleBarColor(taskInfo: RunningTaskInfo): Int {
return if (shouldUseLightCaptionColors(taskInfo)) {
context.getColor(R.color.desktop_mode_caption_handle_bar_light)
@@ -264,18 +281,10 @@ class AppHandleViewHolder(
} ?: false
}
- /** Animate appearance/disappearance of caption handle as the handle menu is animated. */
- private fun animateCaptionHandleAlpha(startValue: Float, endValue: Float) {
- val animator =
- ObjectAnimator.ofFloat(captionHandle, View.ALPHA, startValue, endValue).apply {
- duration = CAPTION_HANDLE_ANIMATION_DURATION
- interpolator = Interpolators.FAST_OUT_SLOW_IN
- }
- animator.start()
+ override fun close() {
+ animator.cancel()
}
- override fun close() {}
-
/** Factory class for creating [AppHandleViewHolder] objects. */
class Factory {
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index 30712b55bdfa..0e2698d0b6fa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -83,6 +83,7 @@ class AppHeaderViewHolder(
val inFullImmersiveState: Boolean,
val hasGlobalFocus: Boolean,
val enableMaximizeLongClick: Boolean,
+ val isCaptionVisible: Boolean,
) : Data()
private val decorThemeUtil = DecorThemeUtil(context)
@@ -264,7 +265,8 @@ class AppHeaderViewHolder(
data.isTaskMaximized,
data.inFullImmersiveState,
data.hasGlobalFocus,
- data.enableMaximizeLongClick
+ data.enableMaximizeLongClick,
+ data.isCaptionVisible,
)
}
@@ -306,6 +308,7 @@ class AppHeaderViewHolder(
inFullImmersiveState: Boolean,
hasGlobalFocus: Boolean,
enableMaximizeLongClick: Boolean,
+ isCaptionVisible: Boolean,
) {
if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue()) {
bindDataWithThemedHeaders(
@@ -314,13 +317,21 @@ class AppHeaderViewHolder(
inFullImmersiveState,
hasGlobalFocus,
enableMaximizeLongClick,
+ isCaptionVisible,
)
} else {
- bindDataLegacy(taskInfo, hasGlobalFocus)
+ bindDataLegacy(taskInfo, hasGlobalFocus, isCaptionVisible)
}
}
- private fun bindDataLegacy(taskInfo: RunningTaskInfo, hasGlobalFocus: Boolean) {
+ private fun bindDataLegacy(
+ taskInfo: RunningTaskInfo,
+ hasGlobalFocus: Boolean,
+ isCaptionVisible: Boolean,
+ ) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
+ setCaptionVisibility(isCaptionVisible)
+ }
captionView.setBackgroundColor(getCaptionBackgroundColor(taskInfo, hasGlobalFocus))
val color = getAppNameAndButtonColor(taskInfo, hasGlobalFocus)
val alpha = Color.alpha(color)
@@ -359,10 +370,15 @@ class AppHeaderViewHolder(
inFullImmersiveState: Boolean,
hasGlobalFocus: Boolean,
enableMaximizeLongClick: Boolean,
+ isCaptionVisible: Boolean,
) {
val header = fillHeaderInfo(taskInfo, hasGlobalFocus)
val headerStyle = getHeaderStyle(header)
+ if (DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
+ setCaptionVisibility(isCaptionVisible)
+ }
+
// Caption Background
when (headerStyle.background) {
is HeaderStyle.Background.Opaque -> {
@@ -464,6 +480,11 @@ class AppHeaderViewHolder(
}
}
+ private fun setCaptionVisibility(visible: Boolean) {
+ val v = if (visible) View.VISIBLE else View.GONE
+ captionView.visibility = v
+ }
+
override fun onHandleMenuOpened() {}
override fun onHandleMenuClosed() {}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
index 509f4f202b6b..8e1cf167318e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
@@ -254,6 +254,16 @@ fun LayersTraceSubject.splitAppLayerBoundsSnapToDivider(
}
}
+/**
+ * Checks that surfaces are still within the expected region after snapping to a snap point.
+ *
+ * @param component The component we are checking (should be one of the two split apps)
+ * @param landscapePosLeft If [true], and device is in left/right split, app is on the left side of
+ * the screen. Has no meaning if device is in top/bottom split.
+ * @param portraitPosTop If [true], and device is in top/bottom split, app is on the top side of
+ * the screen. Has no meaning if device is in left/right split.
+ * @param rotation The rotation state of the display.
+ */
fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
component: IComponentMatcher,
landscapePosLeft: Boolean,
@@ -268,10 +278,12 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
visibleRegion(component).isNotEmpty()
visibleRegion(component)
.coversAtMost(
+ // TODO (b/403082705): Should use the new method for determining left/right split.
if (displayBounds.width() > displayBounds.height()) {
if (landscapePosLeft) {
Region(
- 0,
+ // TODO (b/403304310): Check if we're in an offscreen-enabled mode.
+ -displayBounds.right, // the receding app can go offscreen
0,
(dividerRegion.left + dividerRegion.right) / 2,
displayBounds.bottom
@@ -280,7 +292,7 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
Region(
(dividerRegion.left + dividerRegion.right) / 2,
0,
- displayBounds.right,
+ displayBounds.right * 2, // the receding app can go offscreen
displayBounds.bottom
)
}
@@ -288,7 +300,7 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
if (portraitPosTop) {
Region(
0,
- 0,
+ -displayBounds.bottom, // the receding app can go offscreen
displayBounds.right,
(dividerRegion.top + dividerRegion.bottom) / 2
)
@@ -297,7 +309,7 @@ fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
0,
(dividerRegion.top + dividerRegion.bottom) / 2,
displayBounds.right,
- displayBounds.bottom
+ displayBounds.bottom * 2 // the receding app can go offscreen
)
}
}
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 49d6877a1654..e4183f16ba14 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
@@ -310,12 +310,18 @@ object SplitScreenUtils {
}
}
+ /**
+ * Drags the divider, then releases, making it snap to a new snap point.
+ */
fun dragDividerToResizeAndWait(device: UiDevice, wmHelper: WindowManagerStateHelper) {
+ // Find the first display that is turned on (making the assumption that there is only one).
val displayBounds =
- wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace
- ?: error("Display not found")
+ wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual && it.isOn }
+ ?.layerStackSpace ?: error("Display not found")
val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS)
- dividerBar.drag(Point(displayBounds.width() * 1 / 3, displayBounds.height() * 2 / 3), 200)
+ // Drag to a point on the lower left of the screen -- this will cause the divider to snap
+ // to the left- or bottom-side snap point, shrinking the "primary" test app.
+ dividerBar.drag(Point(displayBounds.width() * 1 / 4, displayBounds.height() * 3 / 4), 200)
wmHelper
.StateSyncBuilder()
diff --git a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
index aa1b24189274..33ea0baa4f6d 100644
--- a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
@@ -18,6 +18,8 @@
<!-- Resources used in WindowDecorationTests -->
<dimen name="test_freeform_decor_caption_height">32dp</dimen>
<dimen name="test_freeform_decor_caption_menu_width">216dp</dimen>
+ <dimen name="test_freeform_shadow_radius">20dp</dimen>
+ <dimen name="test_freeform_corner_radius">16dp</dimen>
<dimen name="test_window_decor_left_outset">10dp</dimen>
<dimen name="test_window_decor_top_outset">20dp</dimen>
<dimen name="test_window_decor_right_outset">30dp</dimen>
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
index 43bcc3b61124..2ef6c558b0b5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
@@ -58,7 +58,8 @@ public class BackProgressAnimatorTest extends ShellTestCase {
/* frameTime = */ 0,
/* progress = */ progress,
/* triggerBack = */ false,
- /* swipeEdge = */ BackEvent.EDGE_LEFT);
+ /* swipeEdge = */ BackEvent.EDGE_LEFT,
+ /* departingAnimationTarget = */ null);
}
@Before
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
index 9d4cc49a7a65..2cc52c5ab9ad 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomCrossActivityBackAnimationTest.kt
@@ -224,7 +224,8 @@ class CustomCrossActivityBackAnimationTest : ShellTestCase() {
/* frameTime = */ 0,
/* progress = */ progress,
/* triggerBack = */ false,
- /* swipeEdge = */ BackEvent.EDGE_LEFT
+ /* swipeEdge = */ BackEvent.EDGE_LEFT,
+ /* departingAnimationTarget = */ null
)
private fun createAnimationTarget(open: Boolean): RemoteAnimationTarget {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
index 3983bfbb2080..75f8d9e819cb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.desktopmode
+import android.animation.AnimatorTestRule
import android.app.ActivityManager
import android.app.ActivityManager.RunningTaskInfo
import android.graphics.Rect
@@ -29,6 +30,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.View
+import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.wm.shell.ShellTestCase
@@ -43,6 +45,7 @@ import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.Before
+import org.junit.Rule
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
@@ -67,6 +70,9 @@ import org.mockito.kotlin.whenever
@RunWith(AndroidTestingRunner::class)
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
class VisualIndicatorViewContainerTest : ShellTestCase() {
+
+ @JvmField @Rule val animatorTestRule = AnimatorTestRule(this)
+
@Mock private lateinit var view: View
@Mock private lateinit var displayLayout: DisplayLayout
@Mock private lateinit var displayController: DisplayController
@@ -297,6 +303,95 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
verify(spyViewContainer, never()).fadeInIndicatorInternal(any(), any(), any(), any())
}
+ @Test
+ @EnableFlags(
+ com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+ com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+ )
+ fun testCreateView_bubblesEnabled_indicatorIsFrameLayout() {
+ val spyViewContainer = setupSpyViewContainer()
+ assertThat(spyViewContainer.indicatorView).isInstanceOf(FrameLayout::class.java)
+ }
+
+ @Test
+ @EnableFlags(
+ com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+ com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+ )
+ fun testFadeInOutBubbleIndicator_addAndRemoveBarIndicator() {
+ setUpBubbleBoundsProvider()
+ val spyViewContainer = setupSpyViewContainer()
+ spyViewContainer.fadeInIndicator(
+ displayLayout,
+ DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR,
+ DEFAULT_DISPLAY,
+ )
+ desktopExecutor.flushAll()
+ animatorTestRule.advanceTimeBy(200)
+ assertThat((spyViewContainer.indicatorView as FrameLayout).getChildAt(0)).isNotNull()
+
+ spyViewContainer.fadeOutIndicator(
+ displayLayout,
+ DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR,
+ finishCallback = null,
+ DEFAULT_DISPLAY,
+ snapEventHandler,
+ )
+ desktopExecutor.flushAll()
+ animatorTestRule.advanceTimeBy(250)
+ assertThat((spyViewContainer.indicatorView as FrameLayout).getChildAt(0)).isNull()
+ }
+
+ @Test
+ @EnableFlags(
+ com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+ com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+ )
+ fun testTransitionIndicator_fullscreenToBubble_addBarIndicator() {
+ setUpBubbleBoundsProvider()
+ val spyViewContainer = setupSpyViewContainer()
+
+ spyViewContainer.transitionIndicator(
+ taskInfo,
+ displayController,
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR,
+ )
+ desktopExecutor.flushAll()
+ animatorTestRule.advanceTimeBy(200)
+
+ assertThat((spyViewContainer.indicatorView as FrameLayout).getChildAt(0)).isNotNull()
+ }
+
+ @Test
+ @EnableFlags(
+ com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+ com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+ )
+ fun testTransitionIndicator_bubbleToFullscreen_removeBarIndicator() {
+ setUpBubbleBoundsProvider()
+ val spyViewContainer = setupSpyViewContainer()
+ spyViewContainer.fadeInIndicator(
+ displayLayout,
+ DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR,
+ DEFAULT_DISPLAY,
+ )
+ desktopExecutor.flushAll()
+ animatorTestRule.advanceTimeBy(200)
+ assertThat((spyViewContainer.indicatorView as FrameLayout).getChildAt(0)).isNotNull()
+
+ spyViewContainer.transitionIndicator(
+ taskInfo,
+ displayController,
+ DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR,
+ DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR,
+ )
+ desktopExecutor.flushAll()
+ animatorTestRule.advanceTimeBy(200)
+
+ assertThat((spyViewContainer.indicatorView as FrameLayout).getChildAt(0)).isNull()
+ }
+
private fun setupSpyViewContainer(): VisualIndicatorViewContainer {
val viewContainer =
VisualIndicatorViewContainer(
@@ -331,7 +426,22 @@ class VisualIndicatorViewContainerTest : ShellTestCase() {
.build()
}
+ private fun setUpBubbleBoundsProvider() {
+ bubbleDropTargetBoundsProvider =
+ object : BubbleDropTargetBoundsProvider {
+ override fun getBubbleBarExpandedViewDropTargetBounds(onLeft: Boolean): Rect {
+ return BUBBLE_INDICATOR_BOUNDS
+ }
+
+ override fun getBarDropTargetBounds(onLeft: Boolean): Rect {
+ return BAR_INDICATOR_BOUNDS
+ }
+ }
+ }
+
companion object {
private val DISPLAY_BOUNDS = Rect(0, 0, 1000, 1000)
+ private val BUBBLE_INDICATOR_BOUNDS = Rect(800, 200, 900, 900)
+ private val BAR_INDICATOR_BOUNDS = Rect(880, 950, 900, 960)
}
}
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 4440d4e801fe..601eb315f394 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
@@ -27,6 +27,7 @@ import com.android.window.flags.Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.DesktopUserRepositories
+import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer.DeskRecreationFactory
import com.android.wm.shell.sysui.ShellController
import com.android.wm.shell.sysui.ShellInit
import com.google.common.truth.Truth.assertThat
@@ -242,6 +243,36 @@ class DesktopRepositoryInitializerTest : ShellTestCase() {
.inOrder()
}
+ @Test
+ @EnableFlags(
+ FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE,
+ FLAG_ENABLE_DESKTOP_WINDOWING_HSUM,
+ FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun initWithPersistence_deskRecreationFailed_deskNotAdded() =
+ runTest(StandardTestDispatcher()) {
+ 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)
+
+ // Make [DESKTOP_ID_2] re-creation fail.
+ repositoryInitializer.deskRecreationFactory =
+ DeskRecreationFactory { userId, destinationDisplayId, deskId ->
+ if (deskId == DESKTOP_ID_2) {
+ null
+ } else {
+ deskId
+ }
+ }
+ repositoryInitializer.initialize(desktopUserRepositories)
+
+ assertThat(desktopUserRepositories.getProfile(USER_ID_1).getDeskIds(DEFAULT_DISPLAY))
+ .containsExactly(DESKTOP_ID_1)
+ }
+
@After
fun tearDown() {
datastoreScope.cancel()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
index 75f6bda4d750..4e8812d34ef4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
@@ -21,6 +21,7 @@ import android.app.TaskInfo
import android.graphics.Rect
import android.os.Parcel
import android.testing.AndroidTestingRunner
+import android.view.Display.DEFAULT_DISPLAY
import android.window.IWindowContainerToken
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
@@ -281,7 +282,8 @@ class GroupedTaskInfoTest : ShellTestCase() {
val task2 = createTaskInfo(id = 2)
val taskInfo = GroupedTaskInfo.forDeskTasks(
- /* deskId = */ 500, listOf(task1, task2), setOf())
+ /* deskId = */ 500, DEFAULT_DISPLAY, listOf(task1, task2), setOf()
+ )
assertThat(taskInfo.deskId).isEqualTo(500)
assertThat(taskInfo.getTaskById(1)).isEqualTo(task1)
@@ -335,6 +337,7 @@ class GroupedTaskInfoTest : ShellTestCase() {
): GroupedTaskInfo {
return GroupedTaskInfo.forDeskTasks(
deskId,
+ DEFAULT_DISPLAY,
freeformTaskIds.map { createTaskInfo(it) }.toList(),
minimizedTaskIds.toSet())
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
index a122c3820dcb..55bff09e0ae2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
@@ -222,7 +222,7 @@ public class HomeTransitionObserverTest extends ShellTestCase {
@Test
@EnableFlags({FLAG_ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX})
- public void startDragToDesktopAborted_doesNotTriggerCallback() throws RemoteException {
+ public void startDragToDesktopAborted_triggersCallback() throws RemoteException {
TransitionInfo info = mock(TransitionInfo.class);
TransitionInfo.Change change = mock(TransitionInfo.Change.class);
ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
@@ -239,7 +239,7 @@ public class HomeTransitionObserverTest extends ShellTestCase {
mHomeTransitionObserver.onTransitionFinished(transition, /* aborted= */ true);
- verify(mListener, never()).onHomeVisibilityChanged(/* isVisible= */ anyBoolean());
+ verify(mListener).onHomeVisibilityChanged(/* isVisible= */ true);
}
@Test
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 f37f2fb14bea..f7b9c3352dea 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
@@ -59,6 +59,7 @@ 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.Point;
import android.graphics.Rect;
@@ -341,7 +342,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
RelayoutParams relayoutParams = new RelayoutParams();
@@ -353,7 +355,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
RelayoutParams relayoutParams = new RelayoutParams();
@@ -364,7 +367,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
RelayoutParams relayoutParams = new RelayoutParams();
@@ -375,7 +379,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
fillRoundedCornersResources(/* fillValue= */ 30);
@@ -387,7 +392,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
fillRoundedCornersResources(/* fillValue= */ 30);
@@ -399,7 +405,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
fillRoundedCornersResources(/* fillValue= */ 30);
@@ -411,7 +418,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
- public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() {
+ @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet_dynamicDisabled() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
fillRoundedCornersResources(/* fillValue= */ 30);
@@ -440,6 +448,107 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mShadowRadiusId).isNotEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mShadowRadiusId).isEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mShadowRadiusId).isEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mShadowRadiusId).isNotEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ updateRelayoutParams(relayoutParams, taskInfo);
+
+ assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+ public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ mMockSplitScreenController,
+ DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
+ DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
+ DEFAULT_IS_STATUSBAR_VISIBLE,
+ DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
+ DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
+ DEFAULT_IS_DRAGGING,
+ new InsetsState(),
+ DEFAULT_HAS_GLOBAL_FOCUS,
+ mExclusionRegion,
+ /* shouldIgnoreCornerRadius= */ true,
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+ DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+ DEFAULT_IS_MOVING_TO_BACK);
+
+ assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY)
public void updateRelayoutParams_appHeader_usesTaskDensity() {
final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
index 0798613ed632..24a46aacde15 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
@@ -63,6 +63,7 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoInteractions
import org.mockito.Mockito.`when`
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@@ -210,6 +211,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
eq(taskPositioner),
)
verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+ verifyNoInteractions(mockMultiDisplayDragMoveIndicatorController)
}
@Test
@@ -248,6 +250,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+ verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
Assert.assertEquals(rectAfterEnd, endBounds)
}
@@ -268,6 +271,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
verify(spyDisplayLayout0, never()).localPxToGlobalDp(any(), any())
verify(spyDisplayLayout0, never()).globalDpToLocalPx(any(), any())
+ verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
}
@Test
@@ -290,6 +294,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+ verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
Assert.assertEquals(rectAfterEnd, endBounds)
}
@@ -346,6 +351,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() {
},
eq(taskPositioner),
)
+ verifyNoInteractions(mockMultiDisplayDragMoveIndicatorController)
}
@Test
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 2e95a979220c..c691dc72b1ea 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
@@ -61,7 +61,8 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.LocaleList;
-import android.testing.AndroidTestingRunner;
+import android.platform.test.annotations.UsesFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.util.DisplayMetrics;
import android.view.AttachedSurfaceControl;
import android.view.Display;
@@ -78,6 +79,7 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
@@ -96,6 +98,9 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -108,7 +113,8 @@ import java.util.function.Supplier;
* atest WMShellUnitTests:WindowDecorationTests
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(ParameterizedAndroidJunit4.class)
+@UsesFlags(com.android.window.flags.Flags.class)
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);
@@ -116,6 +122,12 @@ public class WindowDecorationTests extends ShellTestCase {
private static final int SHADOW_RADIUS = 10;
private static final int STATUS_BAR_INSET_SOURCE_ID = 0;
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return FlagsParameterization.allCombinationsOf(
+ Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX);
+ }
+
private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
new WindowDecoration.RelayoutResult<>();
@@ -156,6 +168,10 @@ public class WindowDecorationTests extends ShellTestCase {
private WindowDecoration.RelayoutParams mRelayoutParams = new WindowDecoration.RelayoutParams();
private int mCaptionMenuWidthId;
+ public WindowDecorationTests(FlagsParameterization flags) {
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() {
mMockSurfaceControlStartT = createMockSurfaceControlTransaction();
@@ -165,8 +181,13 @@ 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.mShadowRadius = SHADOW_RADIUS;
- mRelayoutParams.mCornerRadius = CORNER_RADIUS;
+ if (Flags.enableDynamicRadiusComputationBugfix()) {
+ mRelayoutParams.mShadowRadiusId = R.dimen.test_freeform_shadow_radius;
+ mRelayoutParams.mCornerRadiusId = R.dimen.test_freeform_corner_radius;
+ } else {
+ mRelayoutParams.mShadowRadius = SHADOW_RADIUS;
+ mRelayoutParams.mCornerRadius = CORNER_RADIUS;
+ }
when(mMockDisplayController.getDisplay(Display.DEFAULT_DISPLAY))
.thenReturn(mock(Display.class));
@@ -282,9 +303,21 @@ public class WindowDecorationTests extends ShellTestCase {
any(),
anyInt());
- verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
- verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
- verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, SHADOW_RADIUS);
+ if (Flags.enableDynamicRadiusComputationBugfix()) {
+ final int cornerRadius = WindowDecoration.loadDimensionPixelSize(
+ windowDecor.mDecorWindowContext.getResources(),
+ mRelayoutParams.mCornerRadiusId);
+ verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, cornerRadius);
+ verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, cornerRadius);
+ final int shadowRadius = WindowDecoration.loadDimensionPixelSize(
+ windowDecor.mDecorWindowContext.getResources(),
+ mRelayoutParams.mShadowRadiusId);
+ verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, shadowRadius);
+ } else {
+ verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
+ verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
+ verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, SHADOW_RADIUS);
+ }
assertEquals(300, mRelayoutResult.mWidth);
assertEquals(100, mRelayoutResult.mHeight);
@@ -1198,7 +1231,8 @@ public class WindowDecorationTests extends ShellTestCase {
}
@Override
- public void setTaskFocusState(boolean focused) {}
+ public void setTaskFocusState(boolean focused) {
+ }
}
private class TestWindowDecoration extends WindowDecoration<TestView> {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt
index bc4865a07f7f..2c3009cb8dc4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt
@@ -78,7 +78,8 @@ class AppHandleViewHolderTest : ShellTestCase() {
position = captionPosition,
width = CAPTION_WIDTH,
height = CAPTION_HEIGHT,
- showInputLayer = false
+ showInputLayer = false,
+ isCaptionVisible = true
)
)
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index a592749c5398..6e11d430c5ea 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -55,7 +55,7 @@ status_t CursorWindow::create(const String8 &name, size_t inflatedSize, CursorWi
window->mName = name;
window->mSize = std::min(kInlineSize, inflatedSize);
window->mInflatedSize = inflatedSize;
- window->mData = malloc(window->mSize);
+ window->mData = calloc(window->mSize, 1);
if (!window->mData) goto fail;
window->mReadOnly = false;
diff --git a/libs/hostgraphics/include/gui/BufferItemConsumer.h b/libs/hostgraphics/include/gui/BufferItemConsumer.h
index 5c96c82e061c..b9ff0a774805 100644
--- a/libs/hostgraphics/include/gui/BufferItemConsumer.h
+++ b/libs/hostgraphics/include/gui/BufferItemConsumer.h
@@ -48,6 +48,10 @@ public:
return mConsumer->acquireBuffer(item, presentWhen, 0);
}
+ status_t attachBuffer(BufferItem*, const sp<GraphicBuffer>&) {
+ return INVALID_OPERATION;
+ }
+
status_t releaseBuffer(const BufferItem& item,
const sp<Fence>& releaseFence = Fence::NO_FENCE) {
return OK;
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index a892e887bd43..ab1be7e6128d 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -139,6 +139,7 @@ cc_defaults {
"libandroidfw",
"libcrypto",
"libsync",
+ "libgui",
"libui",
"aconfig_text_flags_c_lib",
"aconfig_view_accessibility_flags_c_lib",
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 9d16ee86739e..7e1eb70ca02b 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -16,6 +16,7 @@
#include "WebViewFunctorManager.h"
+#include <gui/SurfaceComposerClient.h>
#include <log/log.h>
#include <private/hwui/WebViewFunctor.h>
#include <utils/Trace.h>
@@ -43,7 +44,7 @@ public:
static ASurfaceControl* getSurfaceControl() {
ALOG_ASSERT(sCurrentFunctor);
- return sCurrentFunctor->getSurfaceControl();
+ return reinterpret_cast<ASurfaceControl*>(sCurrentFunctor->getSurfaceControl());
}
static void mergeTransaction(ASurfaceTransaction* transaction) {
ALOG_ASSERT(sCurrentFunctor);
@@ -129,12 +130,12 @@ bool WebViewFunctor::prepareRootSurfaceControl() {
renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
if (!activeContext) return false;
- ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+ sp<SurfaceControl> rootSurfaceControl = activeContext->getSurfaceControl();
if (!rootSurfaceControl) return false;
int32_t rgid = activeContext->getSurfaceControlGenerationId();
if (mParentSurfaceControlGenerationId != rgid) {
- reparentSurfaceControl(rootSurfaceControl);
+ reparentSurfaceControl(reinterpret_cast<ASurfaceControl*>(rootSurfaceControl.get()));
mParentSurfaceControlGenerationId = rgid;
}
@@ -210,33 +211,35 @@ void WebViewFunctor::removeOverlays() {
mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
if (mSurfaceControl) {
reparentSurfaceControl(nullptr);
- auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
- funcs.releaseFunc(mSurfaceControl);
mSurfaceControl = nullptr;
}
}
ASurfaceControl* WebViewFunctor::getSurfaceControl() {
ATRACE_NAME("WebViewFunctor::getSurfaceControl");
- if (mSurfaceControl != nullptr) return mSurfaceControl;
+ if (mSurfaceControl != nullptr) {
+ return reinterpret_cast<ASurfaceControl*>(mSurfaceControl.get());
+ }
renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
- ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+ sp<SurfaceControl> rootSurfaceControl = activeContext->getSurfaceControl();
LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
- auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
- mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
- ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
+
+ SurfaceComposerClient* client = rootSurfaceControl->getClient().get();
+ mSurfaceControl = client->createSurface(
+ String8("Webview Overlay SurfaceControl"), 0 /* width */, 0 /* height */,
+ // Format is only relevant for buffer queue layers.
+ PIXEL_FORMAT_UNKNOWN /* format */, ISurfaceComposerClient::eFXSurfaceBufferState,
+ rootSurfaceControl->getHandle());
+
activeContext->prepareSurfaceControlForWebview();
- funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
- funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
- ASURFACE_TRANSACTION_VISIBILITY_SHOW);
- funcs.transactionApplyFunc(transaction);
- funcs.transactionDeleteFunc(transaction);
- return mSurfaceControl;
+ SurfaceComposerClient::Transaction transaction;
+ transaction.setLayer(mSurfaceControl, -1).show(mSurfaceControl).apply();
+ return reinterpret_cast<ASurfaceControl*>(mSurfaceControl.get());
}
void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
@@ -249,8 +252,7 @@ void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
done = activeContext->mergeTransaction(transaction, mSurfaceControl);
}
if (!done) {
- auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
- funcs.transactionApplyFunc(transaction);
+ reinterpret_cast<SurfaceComposerClient::Transaction*>(transaction)->apply();
}
}
@@ -258,11 +260,10 @@ void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
if (mSurfaceControl == nullptr) return;
- auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
- ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
- funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
- mergeTransaction(transaction);
- funcs.transactionDeleteFunc(transaction);
+ SurfaceComposerClient::Transaction transaction;
+ transaction.reparent(mSurfaceControl, sp<SurfaceControl>::fromExisting(
+ reinterpret_cast<SurfaceControl*>(parent)));
+ mergeTransaction(reinterpret_cast<ASurfaceTransaction*>(&transaction));
}
void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) {
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index ec17640f9b5e..ac16f9138384 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -25,7 +25,11 @@
#include <mutex>
#include <vector>
-namespace android::uirenderer {
+namespace android {
+
+class SurfaceControl;
+
+namespace uirenderer {
class WebViewFunctorManager;
@@ -100,7 +104,9 @@ private:
bool mHasContext = false;
bool mCreatedHandle = false;
int32_t mParentSurfaceControlGenerationId = 0;
- ASurfaceControl* mSurfaceControl = nullptr;
+#ifdef __ANDROID__
+ sp<SurfaceControl> mSurfaceControl = nullptr;
+#endif
std::vector<pid_t> mRenderingThreads;
};
@@ -126,4 +132,5 @@ private:
std::vector<sp<WebViewFunctor::Handle>> mActiveFunctors;
};
-} // namespace android::uirenderer
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index d3fc91b65829..b3badd0bd51d 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -203,4 +203,11 @@ flag {
description: "Initialize GraphicBufferAllocater on ViewRootImpl init, to avoid blocking on init during buffer allocation, improving app launch latency."
bug: "389908734"
is_fixed_read_only: true
+}
+
+flag {
+ name: "bitmap_parcel_ashmem_as_immutable"
+ namespace: "system_performance"
+ description: "Whether to parcel implicit copies of bitmaps to ashmem as immutable"
+ bug: "400807118"
} \ No newline at end of file
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index 27d4ac7cef4b..104ece6582f5 100644
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -28,8 +28,18 @@
#include "SkRefCnt.h"
#include "SkStream.h"
#include "SkTypes.h"
+#include "android/binder_parcel.h"
#include "android_nio_utils.h"
+#ifdef __ANDROID__
+#include <com_android_graphics_hwui_flags.h>
+namespace hwui_flags = com::android::graphics::hwui::flags;
+#else
+namespace hwui_flags {
+constexpr bool bitmap_parcel_ashmem_as_immutable() { return false; }
+}
+#endif
+
#define DEBUG_PARCEL 0
static jclass gBitmap_class;
@@ -841,6 +851,23 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
#endif
}
+// Returns whether this bitmap should be written to the parcel as mutable.
+static bool shouldParcelAsMutable(SkBitmap& bitmap, AParcel* parcel) {
+ // If the bitmap is immutable, then parcel as immutable.
+ if (bitmap.isImmutable()) {
+ return false;
+ }
+
+ if (!hwui_flags::bitmap_parcel_ashmem_as_immutable()) {
+ return true;
+ }
+
+ // If we're going to copy the bitmap to ashmem and write that to the parcel,
+ // then parcel as immutable, since we won't be mutating the bitmap after
+ // writing it to the parcel.
+ return !shouldUseAshmem(parcel, bitmap.computeByteSize());
+}
+
static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, jint density,
jobject parcel) {
#ifdef __linux__ // Only Linux support parcel
@@ -855,7 +882,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, j
auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle);
bitmapWrapper->getSkBitmap(&bitmap);
- p.writeInt32(!bitmap.isImmutable());
+ p.writeInt32(shouldParcelAsMutable(bitmap, p.get()));
p.writeInt32(bitmap.colorType());
p.writeInt32(bitmap.alphaType());
SkColorSpace* colorSpace = bitmap.colorSpace();
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index cfec24b17cd4..009974b3c8de 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -53,6 +53,7 @@
#include <src/image/SkImage_Base.h>
#include <thread/CommonPool.h>
#ifdef __ANDROID__
+#include <gui/SurfaceControl.h>
#include <ui/GraphicBufferAllocator.h>
#endif
#include <utils/Color.h>
@@ -217,9 +218,11 @@ static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz,
static void android_view_ThreadedRenderer_setSurfaceControl(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong surfaceControlPtr) {
+#ifdef __ANDROID__
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- ASurfaceControl* surfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControlPtr);
- proxy->setSurfaceControl(surfaceControl);
+ SurfaceControl* surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlPtr);
+ proxy->setSurfaceControl(sp<SurfaceControl>::fromExisting(surfaceControl));
+#endif
}
static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
@@ -684,7 +687,7 @@ static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env,
class CopyRequestAdapter : public CopyRequest {
public:
- CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, Rect srcRect)
+ CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, ::android::uirenderer::Rect srcRect)
: CopyRequest(srcRect), mRefHolder(vm, jCopyRequest) {}
virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override {
@@ -710,8 +713,9 @@ static void android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject c
jobject jCopyRequest) {
JavaVM* vm = nullptr;
LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
- auto copyRequest = std::make_shared<CopyRequestAdapter>(vm, env->NewGlobalRef(jCopyRequest),
- Rect(left, top, right, bottom));
+ auto copyRequest = std::make_shared<CopyRequestAdapter>(
+ vm, env->NewGlobalRef(jCopyRequest),
+ ::android::uirenderer::Rect(left, top, right, bottom));
ANativeWindow* window = fromSurface(env, jsurface);
RenderProxy::copySurfaceInto(window, std::move(copyRequest));
ANativeWindow_release(window);
diff --git a/libs/hwui/platform/host/WebViewFunctorManager.cpp b/libs/hwui/platform/host/WebViewFunctorManager.cpp
index 4ba206b41b39..66646b2da2ef 100644
--- a/libs/hwui/platform/host/WebViewFunctorManager.cpp
+++ b/libs/hwui/platform/host/WebViewFunctorManager.cpp
@@ -45,7 +45,7 @@ void WebViewFunctor::destroyContext() {}
void WebViewFunctor::removeOverlays() {}
ASurfaceControl* WebViewFunctor::getSurfaceControl() {
- return mSurfaceControl;
+ return nullptr;
}
void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {}
diff --git a/libs/hwui/platform/host/renderthread/RenderThread.cpp b/libs/hwui/platform/host/renderthread/RenderThread.cpp
index f9d0f4704e08..ece45304e6d5 100644
--- a/libs/hwui/platform/host/renderthread/RenderThread.cpp
+++ b/libs/hwui/platform/host/renderthread/RenderThread.cpp
@@ -27,8 +27,6 @@ namespace renderthread {
static bool gHasRenderThreadInstance = false;
static JVMAttachHook gOnStartHook = nullptr;
-ASurfaceControlFunctions::ASurfaceControlFunctions() {}
-
bool RenderThread::hasInstance() {
return gHasRenderThreadInstance;
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b248c4bc9ade..d5ac99389d87 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -18,6 +18,12 @@
#include <apex/window.h>
#include <fcntl.h>
+
+#ifdef __ANDROID__
+#include <gui/ITransactionCompletedListener.h>
+#include <gui/SurfaceComposerClient.h>
+#endif
+
#include <gui/TraceUtils.h>
#include <strings.h>
#include <sys/stat.h>
@@ -165,7 +171,9 @@ void CanvasContext::destroy() {
stopDrawing();
setHardwareBuffer(nullptr);
setSurface(nullptr);
+#ifdef __ANDROID__
setSurfaceControl(nullptr);
+#endif
freePrefetchedLayers();
destroyHardwareResources();
mAnimationContext->destroy();
@@ -220,10 +228,15 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
setupPipelineSurface();
}
-void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) {
- if (surfaceControl == mSurfaceControl) return;
+#ifdef __ANDROID__
+sp<SurfaceControl> CanvasContext::getSurfaceControl() const {
+ return mSurfaceControl;
+}
+#endif
- auto funcs = mRenderThread.getASurfaceControlFunctions();
+void CanvasContext::setSurfaceControl(sp<SurfaceControl> surfaceControl) {
+#ifdef __ANDROID__
+ if (surfaceControl == mSurfaceControl) return;
if (surfaceControl == nullptr) {
setASurfaceTransactionCallback(nullptr);
@@ -231,17 +244,23 @@ void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) {
}
if (mSurfaceControl != nullptr) {
- funcs.unregisterListenerFunc(this, &onSurfaceStatsAvailable);
- funcs.releaseFunc(mSurfaceControl);
+ TransactionCompletedListener::getInstance()->removeSurfaceStatsListener(
+ this, reinterpret_cast<void*>(onSurfaceStatsAvailable));
}
- mSurfaceControl = surfaceControl;
+
+ mSurfaceControl = std::move(surfaceControl);
mSurfaceControlGenerationId++;
- mExpectSurfaceStats = surfaceControl != nullptr;
+ mExpectSurfaceStats = mSurfaceControl != nullptr;
if (mExpectSurfaceStats) {
- funcs.acquireFunc(mSurfaceControl);
- funcs.registerListenerFunc(surfaceControl, mSurfaceControlGenerationId, this,
- &onSurfaceStatsAvailable);
+ SurfaceStatsCallback callback = [generationId = mSurfaceControlGenerationId](
+ void* callback_context, nsecs_t, const sp<Fence>&,
+ const SurfaceStats& surfaceStats) {
+ onSurfaceStatsAvailable(callback_context, generationId, surfaceStats);
+ };
+ TransactionCompletedListener::getInstance()->addSurfaceStatsListener(
+ this, reinterpret_cast<void*>(onSurfaceStatsAvailable), mSurfaceControl, callback);
}
+#endif
}
void CanvasContext::setupPipelineSurface() {
@@ -896,17 +915,26 @@ FrameInfo* CanvasContext::getFrameInfoFromLastFew(uint64_t frameNumber, uint32_t
}
void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceControlId,
- ASurfaceControlStats* stats) {
+ const SurfaceStats& stats) {
+#ifdef __ANDROID__
auto* instance = static_cast<CanvasContext*>(context);
- const ASurfaceControlFunctions& functions =
- instance->mRenderThread.getASurfaceControlFunctions();
+ nsecs_t gpuCompleteTime = -1L;
+ if (const auto* fence = std::get_if<sp<Fence>>(&stats.acquireTimeOrFence)) {
+ // We got a fence instead of the acquire time due to latching unsignaled.
+ // Ideally the client could just get the acquire time directly from
+ // the fence instead of calling this function which needs to block.
+ (*fence)->waitForever("acquireFence");
+ gpuCompleteTime = (*fence)->getSignalTime();
+ } else {
+ gpuCompleteTime = std::get<int64_t>(stats.acquireTimeOrFence);
+ }
- nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);
if (gpuCompleteTime == Fence::SIGNAL_TIME_PENDING) {
gpuCompleteTime = -1;
}
- uint64_t frameNumber = functions.getFrameNumberFunc(stats);
+
+ uint64_t frameNumber = stats.eventStats.frameNumber;
FrameInfo* frameInfo = instance->getFrameInfoFromLastFew(frameNumber, surfaceControlId);
@@ -919,6 +947,7 @@ void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceContro
instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter, frameNumber,
surfaceControlId);
}
+#endif
}
// Called by choreographer to do an RT-driven animation
@@ -1140,10 +1169,11 @@ CanvasContext* CanvasContext::getActiveContext() {
return ScopedActiveContext::getActiveContext();
}
-bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
+bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction,
+ const sp<SurfaceControl>& control) {
if (!mASurfaceTransactionCallback) return false;
return std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
- reinterpret_cast<int64_t>(control), getFrameNumber());
+ reinterpret_cast<int64_t>(control.get()), getFrameNumber());
}
void CanvasContext::prepareSurfaceControlForWebview() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 3de8e0516070..655aebada954 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -50,6 +50,9 @@
#include "utils/RingBuffer.h"
namespace android {
+
+class SurfaceStats;
+
namespace uirenderer {
class AnimationContext;
@@ -121,7 +124,9 @@ public:
*/
GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
- ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
+#ifdef __ANDROID__
+ sp<SurfaceControl> getSurfaceControl() const;
+#endif
int32_t getSurfaceControlGenerationId() const { return mSurfaceControlGenerationId; }
// Won't take effect until next EGLSurface creation
@@ -129,7 +134,7 @@ public:
void setHardwareBuffer(AHardwareBuffer* buffer);
void setSurface(ANativeWindow* window, bool enableTimeout = true);
- void setSurfaceControl(ASurfaceControl* surfaceControl);
+ void setSurfaceControl(sp<SurfaceControl> surfaceControl);
bool pauseSurface();
void setStopped(bool stopped);
bool isStopped() { return mStopped || !hasOutputTarget(); }
@@ -207,7 +212,7 @@ public:
// Called when SurfaceStats are available.
static void onSurfaceStatsAvailable(void* context, int32_t surfaceControlId,
- ASurfaceControlStats* stats);
+ const SurfaceStats& stats);
void setASurfaceTransactionCallback(
const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
@@ -218,7 +223,7 @@ public:
mBufferParams = params;
}
- bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
+ bool mergeTransaction(ASurfaceTransaction* transaction, const sp<SurfaceControl>& control);
void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback) {
mPrepareSurfaceControlForWebviewCallback = callback;
@@ -286,7 +291,9 @@ private:
std::unique_ptr<ReliableSurface> mNativeSurface;
// The SurfaceControl reference is passed from ViewRootImpl, can be set to
// NULL to remove the reference
- ASurfaceControl* mSurfaceControl = nullptr;
+#ifdef __ANDROID__
+ sp<SurfaceControl> mSurfaceControl = nullptr;
+#endif
// id to track surface control changes and WebViewFunctor uses it to determine
// whether reparenting is needed also used by FrameMetricsReporter to determine
// if a frame is from an "old" surface (i.e. one that existed before the
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
index 64d38b9ef466..01e8010444c0 100644
--- a/libs/hwui/renderthread/ReliableSurface.cpp
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -149,9 +149,25 @@ ANativeWindowBuffer* ReliableSurface::acquireFallbackBuffer(int error) {
return AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
}
+ int width = -1;
+ int result = mWindow->query(mWindow, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
+ if (result != OK || width < 0) {
+ ALOGW("Failed to query window default width: %s (%d) value=%d", strerror(-result), result,
+ width);
+ width = 1;
+ }
+
+ int height = -1;
+ result = mWindow->query(mWindow, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
+ if (result != OK || height < 0) {
+ ALOGW("Failed to query window default height: %s (%d) value=%d", strerror(-result), result,
+ height);
+ height = 1;
+ }
+
AHardwareBuffer_Desc desc = AHardwareBuffer_Desc{
- .width = 1,
- .height = 1,
+ .width = static_cast<uint32_t>(width),
+ .height = static_cast<uint32_t>(height),
.layers = 1,
.format = mFormat,
.usage = mUsage,
@@ -160,9 +176,9 @@ ANativeWindowBuffer* ReliableSurface::acquireFallbackBuffer(int error) {
};
AHardwareBuffer* newBuffer;
- int result = AHardwareBuffer_allocate(&desc, &newBuffer);
+ result = AHardwareBuffer_allocate(&desc, &newBuffer);
- if (result != NO_ERROR) {
+ if (result != OK) {
// Allocate failed, that sucks
ALOGW("Failed to allocate scratch buffer, error=%d", result);
return nullptr;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index ebfd8fde91f6..e4be5fa8d39e 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -21,6 +21,11 @@
#include <SkPicture.h>
#include <gui/TraceUtils.h>
#include <pthread.h>
+
+#ifdef __ANDROID__
+#include <gui/SurfaceControl.h>
+#endif
+
#include <ui/GraphicBufferAllocator.h>
#include "DeferredLayerUpdater.h"
@@ -115,17 +120,12 @@ void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
});
}
-void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
- auto funcs = mRenderThread.getASurfaceControlFunctions();
- if (surfaceControl) {
- funcs.acquireFunc(surfaceControl);
- }
- mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
- mContext->setSurfaceControl(control);
- if (control) {
- funcs.releaseFunc(control);
- }
+void RenderProxy::setSurfaceControl(sp<SurfaceControl> surfaceControl) {
+#ifdef __ANDROID__
+ mRenderThread.queue().post([this, control = std::move(surfaceControl)]() mutable {
+ mContext->setSurfaceControl(std::move(control));
});
+#endif
}
void RenderProxy::allocateBuffers() {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ad6d54bfcf91..23b3ebd4b360 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -20,7 +20,6 @@
#include <SkRefCnt.h>
#include <android/hardware_buffer.h>
#include <android/native_window.h>
-#include <android/surface_control.h>
#include <cutils/compiler.h>
#include <utils/Functor.h>
@@ -39,6 +38,7 @@ class SkImage;
namespace android {
class GraphicBuffer;
+class SurfaceControl;
class Surface;
namespace uirenderer {
@@ -80,7 +80,7 @@ public:
void setName(const char* name);
void setHardwareBuffer(AHardwareBuffer* buffer);
void setSurface(ANativeWindow* window, bool enableTimeout = true);
- void setSurfaceControl(ASurfaceControl* surfaceControl);
+ void setSurfaceControl(sp<SurfaceControl> surfaceControl);
void allocateBuffers();
bool pause();
void setStopped(bool stopped);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 6ab8e4e0e2ab..5e404247376f 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -55,66 +55,6 @@ static bool gHasRenderThreadInstance = false;
static JVMAttachHook gOnStartHook = nullptr;
-ASurfaceControlFunctions::ASurfaceControlFunctions() {
- void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
- createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
- LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
- "Failed to find required symbol ASurfaceControl_create!");
-
- acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
- LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
- "Failed to find required symbol ASurfaceControl_acquire!");
-
- releaseFunc = (ASC_release) dlsym(handle_, "ASurfaceControl_release");
- LOG_ALWAYS_FATAL_IF(releaseFunc == nullptr,
- "Failed to find required symbol ASurfaceControl_release!");
-
- registerListenerFunc = (ASC_registerSurfaceStatsListener) dlsym(handle_,
- "ASurfaceControl_registerSurfaceStatsListener");
- LOG_ALWAYS_FATAL_IF(registerListenerFunc == nullptr,
- "Failed to find required symbol ASurfaceControl_registerSurfaceStatsListener!");
-
- unregisterListenerFunc = (ASC_unregisterSurfaceStatsListener) dlsym(handle_,
- "ASurfaceControl_unregisterSurfaceStatsListener");
- LOG_ALWAYS_FATAL_IF(unregisterListenerFunc == nullptr,
- "Failed to find required symbol ASurfaceControl_unregisterSurfaceStatsListener!");
-
- getAcquireTimeFunc = (ASCStats_getAcquireTime) dlsym(handle_,
- "ASurfaceControlStats_getAcquireTime");
- LOG_ALWAYS_FATAL_IF(getAcquireTimeFunc == nullptr,
- "Failed to find required symbol ASurfaceControlStats_getAcquireTime!");
-
- getFrameNumberFunc = (ASCStats_getFrameNumber) dlsym(handle_,
- "ASurfaceControlStats_getFrameNumber");
- LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
- "Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
-
- transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
- LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
- "Failed to find required symbol ASurfaceTransaction_create!");
-
- transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
- LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
- "Failed to find required symbol ASurfaceTransaction_delete!");
-
- transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
- LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
- "Failed to find required symbol ASurfaceTransaction_apply!");
-
- transactionReparentFunc = (AST_reparent)dlsym(handle_, "ASurfaceTransaction_reparent");
- LOG_ALWAYS_FATAL_IF(transactionReparentFunc == nullptr,
- "Failed to find required symbol transactionReparentFunc!");
-
- transactionSetVisibilityFunc =
- (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
- LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
- "Failed to find required symbol ASurfaceTransaction_setVisibility!");
-
- transactionSetZOrderFunc = (AST_setZOrder)dlsym(handle_, "ASurfaceTransaction_setZOrder");
- LOG_ALWAYS_FATAL_IF(transactionSetZOrderFunc == nullptr,
- "Failed to find required symbol ASurfaceTransaction_setZOrder!");
-}
-
void RenderThread::extendedFrameCallback(const AChoreographerFrameCallbackData* cbData,
void* data) {
RenderThread* rt = reinterpret_cast<RenderThread*>(data);
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 86fddbae0831..f733c7c58ef3 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -77,49 +77,6 @@ struct VsyncSource {
virtual ~VsyncSource() {}
};
-typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
-typedef void (*ASC_acquire)(ASurfaceControl* control);
-typedef void (*ASC_release)(ASurfaceControl* control);
-
-typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, int32_t id,
- void* context,
- ASurfaceControl_SurfaceStatsListener func);
-typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
- ASurfaceControl_SurfaceStatsListener func);
-
-typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
-typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
-
-typedef ASurfaceTransaction* (*AST_create)();
-typedef void (*AST_delete)(ASurfaceTransaction* transaction);
-typedef void (*AST_apply)(ASurfaceTransaction* transaction);
-typedef void (*AST_reparent)(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl,
- ASurfaceControl* newParentASurfaceControl);
-typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
- ASurfaceControl* surface_control, int8_t visibility);
-typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control,
- int32_t z_order);
-
-struct ASurfaceControlFunctions {
- ASurfaceControlFunctions();
-
- ASC_create createFunc;
- ASC_acquire acquireFunc;
- ASC_release releaseFunc;
- ASC_registerSurfaceStatsListener registerListenerFunc;
- ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
- ASCStats_getAcquireTime getAcquireTimeFunc;
- ASCStats_getFrameNumber getFrameNumberFunc;
-
- AST_create transactionCreateFunc;
- AST_delete transactionDeleteFunc;
- AST_apply transactionApplyFunc;
- AST_reparent transactionReparentFunc;
- AST_setVisibility transactionSetVisibilityFunc;
- AST_setZOrder transactionSetZOrderFunc;
-};
-
class ChoreographerSource;
class DummyVsyncSource;
@@ -166,10 +123,6 @@ public:
void preload();
- const ASurfaceControlFunctions& getASurfaceControlFunctions() {
- return mASurfaceControlFunctions;
- }
-
void trimMemory(TrimLevel level);
void trimCaches(CacheTrimLevel level);
@@ -244,7 +197,6 @@ private:
CacheManager* mCacheManager;
sp<VulkanManager> mVkManager;
- ASurfaceControlFunctions mASurfaceControlFunctions;
std::mutex mJankDataMutex;
};
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index 56d3df3b2555..311d64f6c7e8 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
@@ -52,6 +53,127 @@ public class AudioDeviceVolumeManager {
private static final String TAG = "AudioDeviceVolumeManager";
+ /**
+ * @hide
+ * Volume behavior for an audio device that has no particular volume behavior set. Invalid as
+ * an argument to {@link #setDeviceVolumeBehavior(AudioDeviceAttributes, int)} and should not
+ * be returned by {@link #getDeviceVolumeBehavior(AudioDeviceAttributes)}.
+ */
+ public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
+ /**
+ * @hide
+ * Volume behavior for an audio device where a software attenuation is applied
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
+ /**
+ * @hide
+ * Volume behavior for an audio device where the volume is always set to provide no attenuation
+ * nor gain (e.g. unit gain).
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
+ /**
+ * @hide
+ * Volume behavior for an audio device where the volume is either set to muted, or to provide
+ * no attenuation nor gain (e.g. unit gain).
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
+ /**
+ * @hide
+ * Volume behavior for an audio device where no software attenuation is applied, and
+ * the volume is kept synchronized between the host and the device itself through a
+ * device-specific protocol such as BT AVRCP.
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
+ /**
+ * @hide
+ * Volume behavior for an audio device where no software attenuation is applied, and
+ * the volume is kept synchronized between the host and the device itself through a
+ * device-specific protocol (such as for hearing aids), based on the audio mode (e.g.
+ * normal vs in phone call).
+ * @see AudioManager#setMode(int)
+ * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
+
+ /**
+ * @hide
+ * A variant of {@link #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} where the host cannot reliably set
+ * the volume percentage of the audio device. Specifically, {@link AudioManager#setStreamVolume}
+ * will have no effect, or an unreliable effect.
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5;
+
+ /** @hide */
+ @IntDef({
+ DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+ DEVICE_VOLUME_BEHAVIOR_FULL,
+ DEVICE_VOLUME_BEHAVIOR_FIXED,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeviceVolumeBehavior {}
+
+ /** @hide */
+ @IntDef({
+ DEVICE_VOLUME_BEHAVIOR_UNSET,
+ DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+ DEVICE_VOLUME_BEHAVIOR_FULL,
+ DEVICE_VOLUME_BEHAVIOR_FIXED,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeviceVolumeBehaviorState {}
+
+ /**
+ * Variants of absolute volume behavior that are set in for absolute volume management.
+ * @hide
+ */
+ @IntDef({
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+ DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AbsoluteDeviceVolumeBehavior {}
+
+ /**
+ * @hide
+ * Throws IAE on an invalid volume behavior value
+ * @param volumeBehavior behavior value to check
+ */
+ public static void enforceValidVolumeBehavior(int volumeBehavior) {
+ switch (volumeBehavior) {
+ case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
+ case DEVICE_VOLUME_BEHAVIOR_FULL:
+ case DEVICE_VOLUME_BEHAVIOR_FIXED:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
+ return;
+ default:
+ throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
+ }
+ }
+
/** @hide
* Indicates no special treatment in the handling of the volume adjustment */
public static final int ADJUST_MODE_NORMAL = 0;
@@ -158,7 +280,7 @@ public class AudioDeviceVolumeManager {
android.Manifest.permission.BLUETOOTH_PRIVILEGED })
public void register(boolean register, @NonNull AudioDeviceAttributes device,
@NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment,
- @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+ @AbsoluteDeviceVolumeBehavior int behavior) {
try {
getService().registerDeviceVolumeDispatcherForAbsoluteVolume(register,
this, mPackageName,
@@ -204,6 +326,94 @@ public class AudioDeviceVolumeManager {
/**
* @hide
+ * Sets the volume behavior for an audio output device.
+ * @see #DEVICE_VOLUME_BEHAVIOR_VARIABLE
+ * @see #DEVICE_VOLUME_BEHAVIOR_FULL
+ * @see #DEVICE_VOLUME_BEHAVIOR_FIXED
+ * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
+ * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
+ * @param device the device to be affected
+ * @param deviceVolumeBehavior one of the device behaviors
+ */
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+ })
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+ @DeviceVolumeBehavior int deviceVolumeBehavior) {
+ // verify arguments (validity of device type is enforced in server)
+ Objects.requireNonNull(device);
+ enforceValidVolumeBehavior(deviceVolumeBehavior);
+ // communicate with service
+ final IAudioService service = getService();
+ try {
+ service.setDeviceVolumeBehavior(device, deviceVolumeBehavior, mPackageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ * Returns the volume device behavior for the given audio device
+ * @param device the audio device
+ * @return the volume behavior for the device
+ */
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE,
+ Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+ })
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+ public @DeviceVolumeBehavior int getDeviceVolumeBehavior(
+ @NonNull AudioDeviceAttributes device) {
+ // verify arguments (validity of device type is enforced in server)
+ Objects.requireNonNull(device);
+ // communicate with service
+ final IAudioService service = getService();
+ try {
+ return service.getDeviceVolumeBehavior(device);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ * Returns {@code true} if the volume device behavior is {@link #DEVICE_VOLUME_BEHAVIOR_FULL}.
+ */
+ @TestApi
+ @RequiresPermission(anyOf = {
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ Manifest.permission.QUERY_AUDIO_STATE,
+ Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+ })
+ @SuppressWarnings("UnflaggedApi") // @TestApi without associated feature.
+ public boolean isFullVolumeDevice() {
+ final AudioAttributes attributes = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .build();
+ List<AudioDeviceAttributes> devices;
+ final IAudioService service = getService();
+ try {
+ devices = service.getDevicesForAttributes(attributes);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ for (AudioDeviceAttributes device : devices) {
+ if (getDeviceVolumeBehavior(device) == DEVICE_VOLUME_BEHAVIOR_FULL) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @hide
* Configures a device to use absolute volume model, and registers a listener for receiving
* volume updates to apply on that device
* @param device the audio device set to absolute volume mode
@@ -297,7 +507,7 @@ public class AudioDeviceVolumeManager {
@NonNull @CallbackExecutor Executor executor,
@NonNull OnAudioDeviceVolumeChangedListener vclistener) {
baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
- handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ handlesVolumeAdjustment, DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
/**
@@ -355,12 +565,12 @@ public class AudioDeviceVolumeManager {
@NonNull @CallbackExecutor Executor executor,
@NonNull OnAudioDeviceVolumeChangedListener vclistener) {
baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
- handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ handlesVolumeAdjustment, DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
}
/**
* Base method for configuring a device to use absolute volume behavior, or one of its variants.
- * See {@link AudioManager.AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
+ * See {@link AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
*
* @param behavior the variant of absolute device volume behavior to adopt
*/
@@ -372,7 +582,7 @@ public class AudioDeviceVolumeManager {
@NonNull @CallbackExecutor Executor executor,
@NonNull OnAudioDeviceVolumeChangedListener vclistener,
boolean handlesVolumeAdjustment,
- @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+ @AbsoluteDeviceVolumeBehavior int behavior) {
Objects.requireNonNull(device);
Objects.requireNonNull(volumes);
Objects.requireNonNull(executor);
@@ -417,7 +627,7 @@ public class AudioDeviceVolumeManager {
*/
void onDeviceVolumeBehaviorChanged(
@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int volumeBehavior);
+ @DeviceVolumeBehavior int volumeBehavior);
}
/**
@@ -580,19 +790,19 @@ public class AudioDeviceVolumeManager {
* @param behavior one of the volume behaviors defined in AudioManager
* @return a string for the given behavior
*/
- public static String volumeBehaviorName(@AudioManager.DeviceVolumeBehavior int behavior) {
+ public static String volumeBehaviorName(@DeviceVolumeBehavior int behavior) {
switch (behavior) {
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
+ case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
return "DEVICE_VOLUME_BEHAVIOR_VARIABLE";
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
+ case DEVICE_VOLUME_BEHAVIOR_FULL:
return "DEVICE_VOLUME_BEHAVIOR_FULL";
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
+ case DEVICE_VOLUME_BEHAVIOR_FIXED:
return "DEVICE_VOLUME_BEHAVIOR_FIXED";
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE";
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE";
- case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
+ case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY";
default:
return "invalid volume behavior " + behavior;
@@ -611,7 +821,7 @@ public class AudioDeviceVolumeManager {
@Override
public void dispatchDeviceVolumeBehaviorChanged(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int volumeBehavior) {
+ @DeviceVolumeBehavior int volumeBehavior) {
mDeviceVolumeBehaviorChangedListenerMgr.callListeners((listener) ->
listener.onDeviceVolumeBehaviorChanged(device, volumeBehavior));
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 32af7c6fca68..4aba491c291e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,7 @@ package android.media;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
import static android.content.Context.DEVICE_ID_DEFAULT;
+import static android.media.audio.Flags.FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT;
import static android.media.audio.Flags.autoPublicVolumeApiHardening;
import static android.media.audio.Flags.cacheGetStreamMinMaxVolume;
import static android.media.audio.Flags.cacheGetStreamVolume;
@@ -6659,24 +6660,30 @@ public class AudioManager {
* @hide
* Volume behavior for an audio device where a software attenuation is applied
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_VARIABLE} instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
/**
* @hide
* Volume behavior for an audio device where the volume is always set to provide no attenuation
* nor gain (e.g. unit gain).
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_FULL} instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
/**
* @hide
* Volume behavior for an audio device where the volume is either set to muted, or to provide
* no attenuation nor gain (e.g. unit gain).
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_FIXED} instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
/**
* @hide
@@ -6684,8 +6691,10 @@ public class AudioManager {
* the volume is kept synchronized between the host and the device itself through a
* device-specific protocol such as BT AVRCP.
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
/**
* @hide
@@ -6695,8 +6704,11 @@ public class AudioManager {
* normal vs in phone call).
* @see #setMode(int)
* @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE}
+ * instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
/**
@@ -6704,8 +6716,11 @@ public class AudioManager {
* A variant of {@link #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} where the host cannot reliably set
* the volume percentage of the audio device. Specifically, {@link #setStreamVolume} will have
* no effect, or an unreliable effect.
+ * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY}
+ * instead
*/
@SystemApi
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5;
/** @hide */
@@ -6720,49 +6735,6 @@ public class AudioManager {
@Retention(RetentionPolicy.SOURCE)
public @interface DeviceVolumeBehavior {}
- /** @hide */
- @IntDef({
- DEVICE_VOLUME_BEHAVIOR_UNSET,
- DEVICE_VOLUME_BEHAVIOR_VARIABLE,
- DEVICE_VOLUME_BEHAVIOR_FULL,
- DEVICE_VOLUME_BEHAVIOR_FIXED,
- DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
- DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
- DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface DeviceVolumeBehaviorState {}
-
- /**
- * Variants of absolute volume behavior that are set in {@link AudioDeviceVolumeManager}.
- * @hide
- */
- @IntDef({
- DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
- DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface AbsoluteDeviceVolumeBehavior {}
-
- /**
- * @hide
- * Throws IAE on an invalid volume behavior value
- * @param volumeBehavior behavior value to check
- */
- public static void enforceValidVolumeBehavior(int volumeBehavior) {
- switch (volumeBehavior) {
- case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
- case DEVICE_VOLUME_BEHAVIOR_FULL:
- case DEVICE_VOLUME_BEHAVIOR_FIXED:
- case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
- case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
- case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
- return;
- default:
- throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
- }
- }
-
/**
* @hide
* Sets the volume behavior for an audio output device.
@@ -6773,17 +6745,21 @@ public class AudioManager {
* @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
* @param device the device to be affected
* @param deviceVolumeBehavior one of the device behaviors
+ *
+ * @deprecated use
+ * {@link AudioDeviceVolumeManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)} instead
*/
@SystemApi
@RequiresPermission(anyOf = {
Manifest.permission.MODIFY_AUDIO_ROUTING,
Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
})
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
@DeviceVolumeBehavior int deviceVolumeBehavior) {
// verify arguments (validity of device type is enforced in server)
Objects.requireNonNull(device);
- enforceValidVolumeBehavior(deviceVolumeBehavior);
+ AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
// communicate with service
final IAudioService service = getService();
try {
@@ -6810,6 +6786,8 @@ public class AudioManager {
* Returns the volume device behavior for the given audio device
* @param device the audio device
* @return the volume behavior for the device
+ * @deprecated use
+ * {@link AudioDeviceVolumeManager#getDeviceVolumeBehavior(AudioDeviceAttributes)} instead
*/
@SystemApi
@RequiresPermission(anyOf = {
@@ -6817,6 +6795,7 @@ public class AudioManager {
Manifest.permission.QUERY_AUDIO_STATE,
Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
})
+ @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
public @DeviceVolumeBehavior
int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
// verify arguments (validity of device type is enforced in server)
@@ -6836,29 +6815,6 @@ public class AudioManager {
}
/**
- * @hide
- * Returns {@code true} if the volume device behavior is {@link #DEVICE_VOLUME_BEHAVIOR_FULL}.
- */
- @TestApi
- @RequiresPermission(anyOf = {
- Manifest.permission.MODIFY_AUDIO_ROUTING,
- Manifest.permission.QUERY_AUDIO_STATE,
- Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
- })
- public boolean isFullVolumeDevice() {
- final AudioAttributes attributes = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .build();
- final List<AudioDeviceAttributes> devices = getDevicesForAttributes(attributes);
- for (AudioDeviceAttributes device : devices) {
- if (getDeviceVolumeBehavior(device) == DEVICE_VOLUME_BEHAVIOR_FULL) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Indicate wired accessory connection state change.
* @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
* @param state new connection state: 1 connected, 0 disconnected
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index f3b21bfdaa3c..3b560b7a880e 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -219,13 +219,14 @@ public final class MediaCodecInfo {
private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256;
- private static final class LazyHolder {
- private static final Range<Integer> SIZE_RANGE = Process.is64Bit()
- ? Range.create(1, 32768)
- : Range.create(1, MediaProperties.resolution_limit_32bit().orElse(4096));
- }
- private static Range<Integer> getSizeRange() {
- return LazyHolder.SIZE_RANGE;
+ private static Range<Integer> SIZE_RANGE;
+ private static synchronized Range<Integer> getSizeRange() {
+ if (SIZE_RANGE == null) {
+ SIZE_RANGE = Process.is64Bit()
+ ? Range.create(1, 32768)
+ : Range.create(1, MediaProperties.resolution_limit_32bit().orElse(4096));
+ }
+ return SIZE_RANGE;
}
// found stuff that is not supported by framework (=> this should not happen)
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 7af78b81cda5..03bcc6afc1b7 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -1299,6 +1299,7 @@ public class MediaRecorder implements AudioRouting,
* start() or before setOutputFormat().
* @throws IOException if prepare fails otherwise.
*/
+ @RequiresPermission(value = android.Manifest.permission.RECORD_AUDIO, conditional = true)
public void prepare() throws IllegalStateException, IOException
{
if (mPath != null) {
@@ -1337,6 +1338,7 @@ public class MediaRecorder implements AudioRouting,
* @throws IllegalStateException if it is called before
* prepare() or when the camera is already in use by another app.
*/
+ @RequiresPermission(value = android.Manifest.permission.RECORD_AUDIO, conditional = true)
public native void start() throws IllegalStateException;
/**
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index ce23be8e8fbb..bc9ad8dea004 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,7 +25,7 @@
<string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e wifi"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
<string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolle un dispositivo para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="chooser_title" msgid="2235819929238267637">"Escolle o perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) que queiras configurar"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Escolle o <xliff:g id="PROFILE_NAME">%1$s</xliff:g> que queiras configurar"</string>
<string name="single_device_title" msgid="4199861437545438606">"Buscando <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="summary_watch" msgid="8134580124808507407">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) e acceder a estes permisos do dispositivo (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Queres permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; xestione o dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)?"</string>
diff --git a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
index be711accd542..89e5372b530e 100644
--- a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
+++ b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
@@ -27,6 +27,7 @@ import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.GravityInt;
+import androidx.annotation.IntDef;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -34,21 +35,46 @@ import com.android.settingslib.widget.preference.button.R;
import com.google.android.material.button.MaterialButton;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* A preference handled a button
*/
public class ButtonPreference extends Preference implements GroupSectionDividerMixin {
+ public static final int TYPE_FILLED = 0;
+ public static final int TYPE_TONAL = 1;
+ public static final int TYPE_OUTLINE = 2;
+
+ @IntDef({TYPE_FILLED, TYPE_TONAL, TYPE_OUTLINE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {
+ }
+
+ public static final int SIZE_NORMAL = 0;
+ public static final int SIZE_LARGE = 1;
+ public static final int SIZE_EXTRA_LARGE = 2;
+
+ @IntDef({SIZE_NORMAL, SIZE_LARGE, SIZE_EXTRA_LARGE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Size {
+ }
+
enum ButtonStyle {
- FILLED_NORMAL(0, 0, R.layout.settingslib_expressive_button_filled),
- FILLED_LARGE(0, 1, R.layout.settingslib_expressive_button_filled_large),
- FILLED_EXTRA(0, 2, R.layout.settingslib_expressive_button_filled_extra),
- TONAL_NORMAL(1, 0, R.layout.settingslib_expressive_button_tonal),
- TONAL_LARGE(1, 1, R.layout.settingslib_expressive_button_tonal_large),
- TONAL_EXTRA(1, 2, R.layout.settingslib_expressive_button_tonal_extra),
- OUTLINE_NORMAL(2, 0, R.layout.settingslib_expressive_button_outline),
- OUTLINE_LARGE(2, 1, R.layout.settingslib_expressive_button_outline_large),
- OUTLINE_EXTRA(2, 2, R.layout.settingslib_expressive_button_outline_extra);
+ FILLED_NORMAL(TYPE_FILLED, SIZE_NORMAL, R.layout.settingslib_expressive_button_filled),
+ FILLED_LARGE(TYPE_FILLED, SIZE_LARGE, R.layout.settingslib_expressive_button_filled_large),
+ FILLED_EXTRA(TYPE_FILLED, SIZE_EXTRA_LARGE,
+ R.layout.settingslib_expressive_button_filled_extra),
+ TONAL_NORMAL(TYPE_TONAL, SIZE_NORMAL, R.layout.settingslib_expressive_button_tonal),
+ TONAL_LARGE(TYPE_TONAL, SIZE_LARGE, R.layout.settingslib_expressive_button_tonal_large),
+ TONAL_EXTRA(TYPE_TONAL, SIZE_EXTRA_LARGE,
+ R.layout.settingslib_expressive_button_tonal_extra),
+ OUTLINE_NORMAL(TYPE_OUTLINE, SIZE_NORMAL, R.layout.settingslib_expressive_button_outline),
+ OUTLINE_LARGE(TYPE_OUTLINE, SIZE_LARGE,
+ R.layout.settingslib_expressive_button_outline_large),
+ OUTLINE_EXTRA(TYPE_OUTLINE, SIZE_EXTRA_LARGE,
+ R.layout.settingslib_expressive_button_outline_extra);
private final int mType;
private final int mSize;
@@ -60,7 +86,7 @@ public class ButtonPreference extends Preference implements GroupSectionDividerM
this.mLayoutId = layoutId;
}
- static int getLayoutId(int type, int size) {
+ static int getLayoutId(@Type int type, @Size int size) {
for (ButtonStyle style : values()) {
if (style.mType == type && style.mSize == size) {
return style.mLayoutId;
@@ -266,7 +292,7 @@ public class ButtonPreference extends Preference implements GroupSectionDividerM
* <li>2: extra large</li>
* </ul>
*/
- public void setButtonStyle(int type, int size) {
+ public void setButtonStyle(@Type int type, @Size int size) {
int layoutId = ButtonStyle.getLayoutId(type, size);
setLayoutResource(layoutId);
notifyChanged();
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
index 3db0ac653848..b1e42c0aebff 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
@@ -35,6 +35,7 @@
android:layout_height="@dimen/settingslib_toolbar_layout_height"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:toolbarId="@id/action_bar"
+ app:maxLines="2"
style="@style/SettingsLibCollapsingToolbarLayoutStyle.Expressive">
<Toolbar
@@ -44,7 +45,24 @@
android:layout_marginStart="@dimen/settingslib_expressive_space_extrasmall4"
android:theme="?android:attr/actionBarTheme"
android:transitionName="shared_element_view"
- app:layout_collapseMode="pin"/>
+ app:layout_collapseMode="pin">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/settingslib_expressive_space_extrasmall6"
+ android:layout_marginEnd="@dimen/settingslib_expressive_space_small4"
+ android:layout_gravity="end">
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/action_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@style/SettingsLibButtonStyle.Expressive.Filled"
+ android:visibility="gone"/>
+ </LinearLayout>
+
+ </Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
index feacecbd5d0c..ec1df447995c 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
@@ -24,6 +24,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
+import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
@@ -132,6 +133,29 @@ public class CollapsingToolbarAppCompatActivity extends AppCompatActivity {
setTitle(getText(titleId));
}
+ /**
+ * Show/Hide the action button on the Toolbar.
+ * @param enabled true to show the button, otherwise it's hidden.
+ */
+ public void setActionButtonEnabled(boolean enabled) {
+ getToolbarDelegate().setActionButtonEnabled(enabled);
+ }
+
+ /** Set the icon to the action button */
+ public void setActionButtonIcon(@DrawableRes int drawableRes) {
+ getToolbarDelegate().setActionButtonIcon(this, drawableRes);
+ }
+
+ /** Set the text to the action button */
+ public void setActionButtonText(@Nullable CharSequence text) {
+ getToolbarDelegate().setActionButtonText(text);
+ }
+
+ /** Set the OnClick listener to the action button */
+ public void setActionButtonListener(@Nullable View.OnClickListener listener) {
+ getToolbarDelegate().setActionButtonOnClickListener(listener);
+ }
+
@Override
public boolean onSupportNavigateUp() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 0f9d94e9cc3d..b1b8c983b033 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -25,6 +25,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
+import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
@@ -124,6 +125,29 @@ public class CollapsingToolbarBaseActivity extends FragmentActivity {
setTitle(getText(titleId));
}
+ /**
+ * Show/Hide the action button on the Toolbar.
+ * @param enabled true to show the button, otherwise it's hidden.
+ */
+ public void setActionButtonEnabled(boolean enabled) {
+ getToolbarDelegate().setActionButtonEnabled(enabled);
+ }
+
+ /** Set the icon to the action button */
+ public void setActionButtonIcon(@DrawableRes int drawableRes) {
+ getToolbarDelegate().setActionButtonIcon(this, drawableRes);
+ }
+
+ /** Set the text to the action button */
+ public void setActionButtonText(@Nullable CharSequence text) {
+ getToolbarDelegate().setActionButtonText(text);
+ }
+
+ /** Set the OnClick listener to the action button */
+ public void setActionButtonListener(@Nullable View.OnClickListener listener) {
+ getToolbarDelegate().setActionButtonOnClickListener(listener);
+ }
+
@Override
public boolean onNavigateUp() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
index de0d60916b3d..072b36549093 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
@@ -33,6 +33,7 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Toolbar;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
@@ -42,6 +43,7 @@ import com.android.settingslib.widget.SettingsThemeHelper;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
+import com.google.android.material.button.MaterialButton;
/**
* A delegate that allows to use the collapsing toolbar layout in hosts that doesn't want/need to
@@ -80,6 +82,8 @@ public class CollapsingToolbarDelegate {
private AppBarLayout mAppBarLayout;
@NonNull
private Toolbar mToolbar;
+ @Nullable
+ private MaterialButton mActionButton;
@NonNull
private FrameLayout mContentFrameLayout;
@NonNull
@@ -154,6 +158,7 @@ public class CollapsingToolbarDelegate {
}
autoSetCollapsingToolbarLayoutScrolling();
mContentFrameLayout = view.findViewById(R.id.content_frame);
+ mActionButton = view.findViewById(R.id.action_button);
if (activity instanceof AppCompatActivity) {
Log.d(TAG, "onCreateView: from AppCompatActivity and sub-class.");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -215,6 +220,42 @@ public class CollapsingToolbarDelegate {
}
}
+ /**
+ * Show/Hide the action button on the Toolbar.
+ * @param enabled true to show the button, otherwise it's hidden.
+ */
+ public void setActionButtonEnabled(boolean enabled) {
+ if (mActionButton == null) {
+ return;
+ }
+ int visibility = enabled ? View.VISIBLE : View.GONE;
+ mActionButton.setVisibility(visibility);
+ }
+
+ /** Set the icon to the action button */
+ public void setActionButtonIcon(@NonNull Context context, @DrawableRes int drawableRes) {
+ if (mActionButton == null) {
+ return;
+ }
+ mActionButton.setIcon(context.getResources().getDrawable(drawableRes, context.getTheme()));
+ }
+
+ /** Set the text to the action button */
+ public void setActionButtonText(@Nullable CharSequence text) {
+ if (mActionButton == null) {
+ return;
+ }
+ mActionButton.setText(text);
+ }
+
+ /** Set the OnClick listener to the action button */
+ public void setActionButtonOnClickListener(@Nullable View.OnClickListener listener) {
+ if (mActionButton == null) {
+ return;
+ }
+ mActionButton.setOnClickListener(listener);
+ }
+
/** Return an instance of CoordinatorLayout. */
@Nullable
public CoordinatorLayout getCoordinatorLayout() {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 7f4bebcf4a62..335526632383 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -46,6 +46,8 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import java.util.ArrayList;
@@ -326,6 +328,15 @@ public abstract class Tile implements Parcelable {
return false;
}
+ /** Returns the icon color scheme. */
+ @Nullable
+ public String getIconColorScheme(@NonNull Context context) {
+ ensureMetadataNotStale(context);
+ return mMetaData != null
+ ? mMetaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_COLOR_SCHEME, null)
+ : null;
+ }
+
/** Whether the {@link Activity} should be launched in a separate task. */
public boolean isNewTask() {
if (mMetaData != null && mMetaData.containsKey(META_DATA_NEW_TASK)) {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index ac0b9b45aba6..d62ed2f60ed0 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -135,6 +135,13 @@ public class TileUtils {
public static final String META_DATA_PREFERENCE_ICON = "com.android.settings.icon";
/**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the icon
+ * color scheme. Only available for preferences on the homepage.
+ */
+ public static final String META_DATA_PREFERENCE_ICON_COLOR_SCHEME =
+ "com.android.settings.icon_color_scheme";
+
+ /**
* Name of the meta-data item that should be set in the AndroidManifest.xml
* to specify the icon background color. The value may or may not be used by Settings app.
*/
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 58ddc723b77a..f1859f2fbd6a 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheer deur Beperkte Instellings"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Onbeskikbaar tydens oproepe"</string>
<string name="disabled" msgid="8017887509554714950">"Gedeaktiveer"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Geaktiveer"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Toegelaat"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nie toegelaat nie"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installeer onbekende apps"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AANVULLENDE"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"Aanvullend"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan nie op hierdie toestel speel nie"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Gradeer rekening op om oor te skakel"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan nie aflaaie hier speel nie"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ingeboude luidspreker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-oudio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kan nie koppel nie. Skakel toestel af en weer aan"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedrade oudiotoestel"</string>
<string name="help_label" msgid="3528360748637781274">"Hulp en terugvoer"</string>
<string name="storage_category" msgid="2287342585424631813">"Berging"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 3844a4b69d86..77009d747bad 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"በተገደበ ቅንብር ቁጥጥር የሚደረግበት"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"በጥሪዎች ጊዜ አይገኝም"</string>
<string name="disabled" msgid="8017887509554714950">"ቦዝኗል"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"ነቅቷል"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ይፈቀዳል"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"አይፈቀድም"</string>
<string name="install_other_apps" msgid="3232595082023199454">"ያልታወቁ መተግበሪያዎችን ይጫኑ"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"አብሮ የተሰራ ድምፅ ማውጫ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"የTV ኦዲዮ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"መገናኘት ላይ ችግር። መሳሪያውን ያጥፉት እና እንደገና ያብሩት"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ባለገመድ የኦዲዮ መሣሪያ"</string>
<string name="help_label" msgid="3528360748637781274">"እገዛ እና ግብረመልስ"</string>
<string name="storage_category" msgid="2287342585424631813">"ማከማቻ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 1344a25672d2..a522e07baaec 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"مكبِّر الصوت المُدمَج"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"صوت التلفزيون"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
<string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
<string name="storage_category" msgid="2287342585424631813">"مساحة التخزين"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 56f73df512a1..0ed118be8ae3 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"প্ৰতিবন্ধিত ছেটিঙৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"কল চলি থকাৰ সময়ত উপলব্ধ নহয়"</string>
<string name="disabled" msgid="8017887509554714950">"নিষ্ক্ৰিয়"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"সক্ষম কৰা আছে"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"অনুমতি দিয়া হৈছে"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"অনুমতি দিয়া হোৱা নাই"</string>
<string name="install_other_apps" msgid="3232595082023199454">"অজ্ঞাত এপ্ ইনষ্টল কৰক"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফ’নটো"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"এনালগ"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"অক্স"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইচটো প্লে\' কৰিব নোৱাৰি"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"সলনি কৰিবলৈ একাউণ্ট আপগ্ৰে’ড কৰক"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ইয়াত ডাউনল’ডসমূহ প্লে’ কৰিব নোৱাৰি"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"বিল্ট-ইন স্পীকাৰ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"টিভিৰ অডিঅ’"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"সংযোগ হোৱাত সমস্যা হৈছে। ডিভাইচটো অফ কৰি পুনৰ অন কৰক"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"তাঁৰযুক্ত অডিঅ’ ডিভাইচ"</string>
<string name="help_label" msgid="3528360748637781274">"সহায় আৰু মতামত"</string>
<string name="storage_category" msgid="2287342585424631813">"ষ্ট’ৰেজ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 878d8972e9a8..6ba40f7fcbac 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Daxili dinamik"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audiosu"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Yaddaş"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 97873e5a2d2a..0ebeb554c758 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nedostupno tokom poziva"</string>
<string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk TV-a"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Memorijski prostor"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 78a5eaf388f0..8e1fd28ee242 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Пад кіраваннем Абмежаванага наладжвання"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недаступна падчас выклікаў"</string>
<string name="disabled" msgid="8017887509554714950">"Адключанае"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Уключана"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Дазволена"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Забаронена"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Усталёўка невядомых праграм"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Убудаваны дынамік"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аўдыя тэлевізара"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Праблема з падключэннем. Выключыце і зноў уключыце прыладу"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Правадная аўдыяпрылада"</string>
<string name="help_label" msgid="3528360748637781274">"Даведка і водгукі"</string>
<string name="storage_category" msgid="2287342585424631813">"Сховішча"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index f49b1d2b5adc..bf10d1d94a39 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -610,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Свързано устройство"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Този телефон"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов аудиоизход"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Възпроизвеждането не е възможно на това устройство"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надстройте профила, за да превключите"</string>
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вграден високоговорител"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудио на телевизора"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"При свързването възникна проблем. Изключете устройството и го включете отново"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Аудиоустройство с кабел"</string>
<string name="help_label" msgid="3528360748637781274">"Помощ и отзиви"</string>
<string name="storage_category" msgid="2287342585424631813">"Хранилище"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 79e4ed9600aa..5f37d44c3626 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"এটি বিধিনিষেধ সেটিং থেকে নিয়ন্ত্রণ করা হয়"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"কল চলাকালীন উপলভ্য হবে না"</string>
<string name="disabled" msgid="8017887509554714950">"অক্ষম হয়েছে"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"চালু করা আছে"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"অনুমোদিত"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"অনুমোদিত নয়"</string>
<string name="install_other_apps" msgid="3232595082023199454">"অজানা অ্যাপ ইনস্টল করা"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"বিল্ট-ইন স্পিকার"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"টিভি অডিও"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"কানেক্ট করতে সমস্যা হচ্ছে। ডিভাইস বন্ধ করে আবার চালু করুন"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ওয়্যার অডিও ডিভাইস"</string>
<string name="help_label" msgid="3528360748637781274">"সহায়তা ও মতামত"</string>
<string name="storage_category" msgid="2287342585424631813">"স্টোরেজ"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index d06ce341fa99..8cc8199ce07e 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nije dostupno tokom poziva"</string>
<string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk TV-a"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Došlo je do problema prilikom povezivanja. Isključite, pa ponovo uključite uređaj"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Pohrana"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 776caae3b828..ee683e57b783 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per l\'opció de configuració restringida"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No està disponible durant les trucades"</string>
<string name="disabled" msgid="8017887509554714950">"Desactivat"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Activat"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Amb permís"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Sense permís"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instal·la aplicacions desconegudes"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altaveu integrat"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Àudio de la televisió"</string>
<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>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Emmagatzematge"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 02722fd98959..58cdc19c5c73 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Spravováno omezeným nastavením"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Při volání nedostupné"</string>
<string name="disabled" msgid="8017887509554714950">"Deaktivováno"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Zapnuto"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Povoleno"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Není povoleno"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalace neznámých aplikací"</string>
@@ -611,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Připojené zařízení"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogové"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogový výstup"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"V zařízení nelze přehrávat"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Účet je třeba upgradovat"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vestavěný reproduktor"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk televize"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problém s připojením. Vypněte zařízení a znovu jej zapněte"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Úložiště"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 4d37578c68b9..257f673c93dd 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styres af en begrænset indstilling"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Kan ikke bruges under opkald"</string>
<string name="disabled" msgid="8017887509554714950">"Deaktiveret"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aktiveret"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Tilladt"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tilladt"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installer ukendte apps"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Indbygget højttaler"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-lyd"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
<string name="help_label" msgid="3528360748637781274">"Hjælp og feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Lager"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 3e57002a7a59..8bfaa0e0aeb9 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gesteuert durch eingeschränkte Einstellung"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Während Anrufen nicht verfügbar"</string>
<string name="disabled" msgid="8017887509554714950">"Deaktiviert"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aktiviert"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Zugelassen"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nicht zugelassen"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installieren unbekannter Apps"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Integrierter Lautsprecher"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV‑Audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus und wieder ein."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
<string name="help_label" msgid="3528360748637781274">"Hilfe und Feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Speicher"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index be1135690e62..83fb6ff6ed70 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ελέγχεται από τη Ρύθμιση με περιορισμό"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Μη διαθέσιμη κατά τη διάρκεια κλήσεων"</string>
<string name="disabled" msgid="8017887509554714950">"Απενεργοποιημένη"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Ενεργό"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Επιτρέπεται"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Δεν επιτρέπεται"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Εγκατ. άγνωστων εφ."</string>
@@ -611,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Συνδεδεμένη συσκευή"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφ."</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογικός"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογική έξοδος"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Δεν είναι δυνατή η αναπαραγωγή σε αυτήν τη συσκευή"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Αναβαθμίστε τον λογαριασμό για εναλλαγή"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ενσωματωμένο ηχείο"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Ήχος τηλεόρασης"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Πρόβλημα κατά τη σύνδεση. Απενεργοποιήστε τη συσκευή και ενεργοποιήστε την ξανά"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ενσύρματη συσκευή ήχου"</string>
<string name="help_label" msgid="3528360748637781274">"Βοήθεια και σχόλια"</string>
<string name="storage_category" msgid="2287342585424631813">"Αποθηκευτικός χώρος"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8c819ac742a1..e2e3851eb3fd 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
<string name="disabled" msgid="8017887509554714950">"Disabled"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 2faf2feed627..002b1049cb13 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -627,6 +627,7 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off &amp; back on"</string>
+ <string name="bluetooth_key_missing_subtext" msgid="1003639333895028298">"Can’t connect"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8c819ac742a1..e2e3851eb3fd 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
<string name="disabled" msgid="8017887509554714950">"Disabled"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8c819ac742a1..e2e3851eb3fd 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
<string name="disabled" msgid="8017887509554714950">"Disabled"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 0e83356e185f..17909f984640 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Bocina integrada"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio de la TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Error al establecer la conexión. Apaga el dispositivo y vuelve a encenderlo."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 66d81d27a807..536f0995a001 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por ajustes restringidos"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No disponible durante las llamadas"</string>
<string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Habilitado"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Autorizadas"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"No autorizadas"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalar aplicaciones desconocidas"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altavoz integrado"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio de la televisión"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 59e1e4b4bc95..86ccf28c65a1 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Haldavad piiranguga seaded"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Pole kõnede ajal saadaval"</string>
<string name="disabled" msgid="8017887509554714950">"Keelatud"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Lubatud"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Lubatud"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Pole lubatud"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Tundmatute rakenduste installimine"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Sisseehitatud kõlar"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Teleri heli"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem ühendamisel. Lülitage seade välja ja uuesti sisse"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Juhtmega heliseade"</string>
<string name="help_label" msgid="3528360748637781274">"Abi ja tagasiside"</string>
<string name="storage_category" msgid="2287342585424631813">"Salvestusruum"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6fd7e24b8c8b..4de40f53df0e 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -628,6 +628,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Bozgorailu integratua"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Telebistako audioa"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Arazo bat izan da konektatzean. Itzali gailua eta pitz ezazu berriro."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
<string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
<string name="storage_category" msgid="2287342585424631813">"Biltegiratzea"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 483e76ab4369..f3fa38b1ded1 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"بلندگوی داخلی"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"صدای تلویزیون"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"مشکل در اتصال. دستگاه را خاموش و دوباره روشن کنید"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"دستگاه صوتی سیمی"</string>
<string name="help_label" msgid="3528360748637781274">"راهنما و بازخورد"</string>
<string name="storage_category" msgid="2287342585424631813">"فضای ذخیره‌سازی"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index f6af16e74ecb..e212f0911530 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Rajoitettujen asetusten mukaisesti"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ei käytettävissä puhelujen aikana"</string>
<string name="disabled" msgid="8017887509554714950">"Pois päältä"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Käytössä"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Sallittu"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Ei sallittu"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Asenna tuntemattomia sovelluksia"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Sisäänrakennettu kaiutin"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV:n audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Langallinen äänilaite"</string>
<string name="help_label" msgid="3528360748637781274">"Ohjeet ja palaute"</string>
<string name="storage_category" msgid="2287342585424631813">"Tallennustila"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index a5b212b432cb..7c3c84408f4a 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Haut-parleur intégré"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sortie audio du téléviseur"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez et rallumez l\'appareil"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
<string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
<string name="storage_category" msgid="2287342585424631813">"Stockage"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4cc8a9a37632..1053e15d23c3 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponible pendant les appels"</string>
<string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Activé"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Autorisé"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisé"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installation d\'applis inconnues"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Haut-parleur intégré"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio filaire"</string>
<string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
<string name="storage_category" msgid="2287342585424631813">"Stockage"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 352b6082081a..618dd62d248b 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Baixo o control de opcións restrinxidas"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Non dispoñible durante as chamadas"</string>
<string name="disabled" msgid="8017887509554714950">"Desactivada"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Opción activada"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Permiso concedido"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Permiso non concedido"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalar aplicacións descoñecidas"</string>
@@ -626,8 +625,10 @@
<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_internal_speakers" msgid="4662765121700213785">"Altofalante integrado"</string>
- <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio da televisión"</string>
+ <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Saída de audio da televisión"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Produciuse un problema coa conexión. Apaga e acende o dispositivo."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Almacenamento"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index aa27f2a8a09b..9f8fc1046920 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"પ્રતિબંધિત સેટિંગ દ્વારા નિયંત્રિત"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"કૉલ દરમિયાન અનુપલબ્ધ"</string>
<string name="disabled" msgid="8017887509554714950">"બંધ કરી"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"ચાલુ છે"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"મંજૂરી છે"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"મંજૂરી નથી"</string>
<string name="install_other_apps" msgid="3232595082023199454">"અજાણી ઍપ ઇન્સ્ટૉલ કરો"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"આ ફોન"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"એનાલોગ"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ઑગ્ઝિલરી"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"આ ડિવાઇસ પર ચલાવી શકતા નથી"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"સ્વિચ કરવા માટે એકાઉન્ટ અપગ્રેડ કરો"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ડાઉનલોડ કરેલું કન્ટેન્ટ અહીં ચલાવી શકતા નથી"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"બિલ્ટ-ઇન સ્પીકર"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ટીવીનો ઑડિયો"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"કનેક્ટ કરવામાં સમસ્યા આવી રહી છે. ડિવાઇસને બંધ કરીને ફરી ચાલુ કરો"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"વાયરવાળો ઑડિયો ડિવાઇસ"</string>
<string name="help_label" msgid="3528360748637781274">"સહાય અને પ્રતિસાદ"</string>
<string name="storage_category" msgid="2287342585424631813">"સ્ટોરેજ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7c4d64f32cda..cb6e3c90e7ca 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"इसे पाबंदी मोड वाली सेटिंग से कंट्रोल किया जाता है"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कॉल के दौरान उपलब्ध नहीं है"</string>
<string name="disabled" msgid="8017887509554714950">"बंद किया गया"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"चालू है"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"अनुमति है"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति नहीं है"</string>
<string name="install_other_apps" msgid="3232595082023199454">"अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"यह फ़ोन"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ऐनालॉग"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ऑक्स"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"सहायक डिवाइस"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"इस डिवाइस पर मीडिया नहीं चलाया जा सकता"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"प्रीमियम खाते में स्विच करने के लिए, अपना खाता अपग्रेड करें"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड किए गए वीडियो यहां नहीं चलाए जा सकते"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"डिवाइस में पहले से मौजूद स्पीकर"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टीवी ऑडियो"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्ट करने में समस्या हो रही है. डिवाइस को बंद करके चालू करें"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर वाला ऑडियो डिवाइस"</string>
<string name="help_label" msgid="3528360748637781274">"सहायता और सुझाव"</string>
<string name="storage_category" msgid="2287342585424631813">"डिवाइस का स्टोरेज"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ba5650f1d7a5..10863cf62551 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nije dostupno tijekom poziva"</string>
<string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Dopušteno"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nije dopušteno"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalacija nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV zvuk"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Pohrana"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index faeec8d6ed24..104e4bca7bd0 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Korlátozott beállítás vezérli"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nem áll rendelkezésre hívások közben"</string>
<string name="disabled" msgid="8017887509554714950">"Letiltva"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Engedélyezve"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Engedélyezett"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nem engedélyezett"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Ismeretlen alkalmazások telepítése"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Beépített hangszóró"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tévés hangkimenet"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Tárhely"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index eedd262af0f4..a5a15f98b631 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ներկառուցված բարձրախոս"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Հեռուստացույցի աուդիո"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Կապի խնդիր կա: Սարքն անջատեք և նորից միացրեք:"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Լարով աուդիո սարք"</string>
<string name="help_label" msgid="3528360748637781274">"Օգնություն և հետադարձ կապ"</string>
<string name="storage_category" msgid="2287342585424631813">"Տարածք"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7af3de0da4fe..c8d7481ecd33 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikontrol oleh Setelan Terbatas"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Tidak tersedia selama panggilan berlangsung"</string>
<string name="disabled" msgid="8017887509554714950">"Dinonaktifkan"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aktif"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Diizinkan"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Tidak diizinkan"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instal aplikasi tidak dikenal"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Speaker bawaan"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ada masalah saat menghubungkan. Nonaktifkan perangkat &amp; aktifkan kembali"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Perangkat audio berkabel"</string>
<string name="help_label" msgid="3528360748637781274">"Bantuan &amp; masukan"</string>
<string name="storage_category" msgid="2287342585424631813">"Penyimpanan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index e6ef20fcd908..f85c20b4b9fb 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Stýrt af takmarkaði stillingu"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ekki í boði á meðan á símtölum stendur"</string>
<string name="disabled" msgid="8017887509554714950">"Óvirkt"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Kveikt"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Heimilað"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Ekki heimilað"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Setja upp óþekkt forrit"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Innbyggður hátalari"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sjónvarpshljóð"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Vandamál í tengingu. Slökktu og kveiktu á tækinu"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Geymsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 24e7a4cfe45d..1b31ae012b67 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gestita tramite impostazioni con restrizioni"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Non disponibile durante le chiamate"</string>
<string name="disabled" msgid="8017887509554714950">"Disattivato"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Attivata"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Autorizzazione concessa"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Autorizzazione non concessa"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installa app sconosciute"</string>
@@ -611,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo connesso"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo smartphone"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogico"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogica"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossibile riprodurre su questo dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Esegui l\'upgrade dell\'account per cambiare"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altoparlante integrato"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio della TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema di connessione. Spegni e riaccendi il dispositivo"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo audio cablato"</string>
<string name="help_label" msgid="3528360748637781274">"Guida e feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Archiviazione"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 82d90430090b..0da5795be3c6 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"בשליטה של הגדרה מוגבלת"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ההעדפה הזו לא זמינה במהלך שיחות"</string>
<string name="disabled" msgid="8017887509554714950">"מושבת"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"מופעלת"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"מורשה"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"לא מורשה"</string>
<string name="install_other_apps" msgid="3232595082023199454">"התקנת אפליקציות לא מוכרות"</string>
@@ -611,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"המכשיר המחובר"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"אנלוגי"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"חיבור אנלוגי"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"לא ניתן להפעיל במכשיר"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"יש לשדרג חשבון כדי לעבור"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"רמקול מובנה"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"אודיו בטלוויזיה"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"יש בעיה בחיבור. עליך לכבות את המכשיר ולהפעיל אותו מחדש"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"התקן אודיו חוטי"</string>
<string name="help_label" msgid="3528360748637781274">"עזרה ומשוב"</string>
<string name="storage_category" msgid="2287342585424631813">"אחסון"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index adf5b71a7ea3..78c16de0f63b 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"内蔵スピーカー"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV オーディオ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
<string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
<string name="storage_category" msgid="2287342585424631813">"ストレージ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index e9368aa05904..a7599bedd83d 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ჩაშენებული დინამიკი"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"დაკავშირებისას წარმოიქმნა პრობლემა. გამორთეთ და კვლავ ჩართეთ მოწყობილობა"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"სადენიანი აუდიო მოწყობილობა"</string>
<string name="help_label" msgid="3528360748637781274">"დახმარება და გამოხმაურება"</string>
<string name="storage_category" msgid="2287342585424631813">"საცავი"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 16b7c22b6bfe..65ad80ab18b7 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Шектелген параметрлер арқылы басқарылады."</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Қоңырау шалу кезінде қолжетімді емес."</string>
<string name="disabled" msgid="8017887509554714950">"Өшірілген"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Қосулы"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Рұқсат берілген"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Рұқсат етілмеген"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Белгісіз қолданбаларды орнату"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ендірілген динамик"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Теледидардың аудио шығысы"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Байланыс орнату қатесі шығуып жатыр. Құрылғыны өшіріп, қайта қосыңыз."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Сымды аудио құрылғысы"</string>
<string name="help_label" msgid="3528360748637781274">"Анықтама және пікір"</string>
<string name="storage_category" msgid="2287342585424631813">"Жад"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index b183dc926c2d..b8a8355a7249 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -624,9 +624,11 @@
<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_internal_speakers" msgid="4662765121700213785">"ឧបករណ៍បំពងសំឡេង​ភ្ជាប់មកជាមួយ"</string>
+ <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ឧបករណ៍សំឡេងមកជាមួយ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"សំឡេងទូរទស្សន៍"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"មាន​បញ្ហា​ក្នុងការ​ភ្ជាប់។ បិទ រួច​បើក​ឧបករណ៍​វិញ"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ឧបករណ៍​សំឡេងប្រើខ្សែ"</string>
<string name="help_label" msgid="3528360748637781274">"ជំនួយ និងមតិកែលម្អ"</string>
<string name="storage_category" msgid="2287342585424631813">"ទំហំផ្ទុក"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a4e01d96761a..4a8a4135e98e 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ಅಂತರ್ ನಿರ್ಮಿತ ಧ್ವನಿ ವರ್ಧಕ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV ಆಡಿಯೊ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ಕನೆಕ್ಟ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ ಸಾಧನವನ್ನು ಆಫ್ ಮಾಡಿ ಹಾಗೂ ನಂತರ ಪುನಃ ಆನ್ ಮಾಡಿ"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ವೈರ್ ಹೊಂದಿರುವ ಆಡಿಯೋ ಸಾಧನ"</string>
<string name="help_label" msgid="3528360748637781274">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string>
<string name="storage_category" msgid="2287342585424631813">"ಸಂಗ್ರಹಣೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 0488543f7790..ee99bebf7663 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"제한된 설정으로 제어됨"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"통화 중에는 사용할 수 없습니다."</string>
<string name="disabled" msgid="8017887509554714950">"사용 안함"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"사용 설정됨"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"허용됨"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"허용되지 않음"</string>
<string name="install_other_apps" msgid="3232595082023199454">"알 수 없는 앱 설치"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"내장 스피커"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV 오디오"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"연결 중에 문제가 발생했습니다. 기기를 껐다가 다시 켜 보세요."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"유선 오디오 기기"</string>
<string name="help_label" msgid="3528360748637781274">"고객센터"</string>
<string name="storage_category" msgid="2287342585424631813">"저장용량"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b04883747ee7..5a8a66f7fee9 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Чектелген параметр аркылуу көзөмөлдөнөт"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Сүйлөшүп жаткан учурда жеткиликсиз"</string>
<string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Иштетилди"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Уруксат берилген"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Тыюу салынган"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Белгисиз колдонмолорду орнотуу"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналог"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"КШМЧ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Бул түзмөктө ойнотууга болбойт"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Премиум аккаунтка которулуу керек"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктөлүп алынгандар ойнотулбайт"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Алдын ала орнотулган динамик"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Сыналгы аудиосу"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Туташууда маселе келип чыкты. Түзмөктү өчүрүп, кайра күйгүзүп көрүңүз"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Зымдуу аудио түзмөк"</string>
<string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
<string name="storage_category" msgid="2287342585424631813">"Сактагыч"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index ebba474c243e..c60c04d668e8 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ລຳໂພງທີ່ມີໃນຕົວ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ສຽງນີ້"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ເກີດບັນຫາໃນການເຊື່ອມຕໍ່. ປິດອຸປະກອນແລ້ວເປີດກັບຄືນມາໃໝ່"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ອຸປະກອນສຽງແບບມີສາຍ"</string>
<string name="help_label" msgid="3528360748637781274">"ຊ່ວຍເຫຼືອ ແລະ ຕິຊົມ"</string>
<string name="storage_category" msgid="2287342585424631813">"ບ່ອນເກັບຂໍ້ມູນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 058ca607a078..6467e89840e2 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Įtaisytas garsiakalbis"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV garso įrašas"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Prisijungiant kilo problema. Išjunkite įrenginį ir vėl jį įjunkite"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Laidinis garso įrenginys"</string>
<string name="help_label" msgid="3528360748637781274">"Pagalba ir atsiliepimai"</string>
<string name="storage_category" msgid="2287342585424631813">"Saugykla"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index cdca19b8e0c8..ab9dfd54d6ab 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolē ierobežots iestatījums"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ierīce nav pieejama zvanu laikā"</string>
<string name="disabled" msgid="8017887509554714950">"Atspējots"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Iespējots"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Atļauts"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nav atļauts"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Nezināmu lietotņu instalēšana"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Iebūvēts skaļrunis"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Televizora audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Radās problēma ar savienojuma izveidi. Izslēdziet un atkal ieslēdziet ierīci."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Krātuve"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index e51ca04022a7..71d9b76e2f38 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролирано со ограничени поставки"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недостапно при повици"</string>
<string name="disabled" msgid="8017887509554714950">"Оневозможено"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Овозможено"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Со дозвола"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Без дозвола"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознати апликации"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вграден звучник"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудио на телевизор"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем со поврзување. Исклучете го уредот и повторно вклучете го"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичен аудиоуред"</string>
<string name="help_label" msgid="3528360748637781274">"Помош и повратни информации"</string>
<string name="storage_category" msgid="2287342585424631813">"Простор"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 54b6ff8ab524..d9c9629a5d40 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"നിയന്ത്രിത ക്രമീകരണം ഉപയോഗിച്ച് നിയന്ത്രിക്കുന്നത്"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"കോളുകൾ ചെയ്യുമ്പോൾ ലഭ്യമല്ല"</string>
<string name="disabled" msgid="8017887509554714950">"പ്രവർത്തനരഹിതമാക്കി"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"അനുവദനീയം"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"അനുവദിച്ചിട്ടില്ല"</string>
<string name="install_other_apps" msgid="3232595082023199454">"പരിചയമില്ലാത്ത ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ബിൽട്ട്-ഇൻ സ്പീക്കർ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ടിവി ഓഡിയോ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"കണക്‌റ്റ് ചെയ്യുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഉപകരണം ഓഫാക്കി വീണ്ടും ഓണാക്കുക"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"വയർ മുഖേന ബന്ധിപ്പിച്ച ഓഡിയോ ഉപകരണം"</string>
<string name="help_label" msgid="3528360748637781274">"സഹായവും ഫീഡ്‌ബാക്കും"</string>
<string name="storage_category" msgid="2287342585424631813">"സ്റ്റോറേജ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index ed42362e5c1e..829b1d7181df 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Хязгаарлагдсан тохиргоогоор хянадаг"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Дуудлагын үер боломжгүй"</string>
<string name="disabled" msgid="8017887509554714950">"Идэвхгүйжүүлсэн"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Идэвхжүүлсэн"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Зөвшөөрсөн"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Зөвшөөрөөгүй"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Тодорхойгүй апп суулгах"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Бүрэлдэхүүн чанга яригч"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ТВ-ийн аудио"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Холбогдоход асуудал гарлаа. Төхөөрөмжийг унтраагаад дахин асаана уу"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Утастай аудио төхөөрөмж"</string>
<string name="help_label" msgid="3528360748637781274">"Тусламж, санал хүсэлт"</string>
<string name="storage_category" msgid="2287342585424631813">"Хадгалах сан"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 6e7cd02b1e61..8207174f0a0f 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबंधित केलेल्या सेटिंग द्वारे नियंत्रित"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कॉल दरम्‍यान उपलब्ध नाही"</string>
<string name="disabled" msgid="8017887509554714950">"अक्षम"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"सुरू केले आहे"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"अनुमती आहे"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"अनुमती नाही"</string>
<string name="install_other_apps" msgid="3232595082023199454">"अज्ञात अ‍ॅप्स इंस्टॉल करा"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"बिल्ट-इन स्पीकर"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टीव्ही ऑडिओ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
<string name="help_label" msgid="3528360748637781274">"मदत आणि फीडबॅक"</string>
<string name="storage_category" msgid="2287342585424631813">"स्टोरेज"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 384635a97ef8..ea3d78e4aa93 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Pembesar suara terbina dalam"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Masalah penyambungan. Matikan &amp; hidupkan kembali peranti"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Peranti audio berwayar"</string>
<string name="help_label" msgid="3528360748637781274">"Bantuan &amp; maklum balas"</string>
<string name="storage_category" msgid="2287342585424631813">"Storan"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index fc26db0df2e0..c484a741bc2f 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -624,9 +624,11 @@
<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_internal_speakers" msgid="4662765121700213785">"မူလပါရှိသည့် စပီကာ"</string>
+ <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"အသင့်ပါ စပီကာ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV အသံ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ချိတ်ဆက်ရာတွင် ပြဿနာရှိပါသည်။ စက်ကိုပိတ်ပြီး ပြန်ဖွင့်ပါ"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ကြိုးတပ် အသံစက်ပစ္စည်း"</string>
<string name="help_label" msgid="3528360748637781274">"အကူအညီနှင့် အကြံပြုချက်"</string>
<string name="storage_category" msgid="2287342585424631813">"သိုလှောင်ခန်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index c8fc415528b4..3c06c685aa7b 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollert av en begrenset innstilling"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Utilgjengelig under samtaler"</string>
<string name="disabled" msgid="8017887509554714950">"Deaktivert"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Slått på"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Tillatt"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tillatt"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installer ukjente apper"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Innebygd høyttaler"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-lyd"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
<string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
<string name="storage_category" msgid="2287342585424631813">"Lagring"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 5f09635e19c7..fe743e8330fb 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबन्धित सेटिङले नियन्त्रण गरेको"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कल चलिरहेका बेला उपलब्ध छैन"</string>
<string name="disabled" msgid="8017887509554714950">"असक्षम पारियो"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"अन गरियो"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"अनुमति छ"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति छैन"</string>
<string name="install_other_apps" msgid="3232595082023199454">"अज्ञात एप इन्स्टल गर्ने अनुमति"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"अन्तर्निर्मित स्पिकर"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टिभीको अडियो"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
<string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
<string name="storage_category" msgid="2287342585424631813">"भण्डारण"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 78dfdcead634..f49829f2e834 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheerd door beperkte instelling"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Niet beschikbaar tijdens gesprekken"</string>
<string name="disabled" msgid="8017887509554714950">"Uitgezet"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aangezet"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Toegestaan"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Niet toegestaan"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Onbekende apps installeren"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ingebouwde speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tv-audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem bij verbinding maken. Zet het apparaat uit en weer aan."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedraad audioapparaat"</string>
<string name="help_label" msgid="3528360748637781274">"Hulp en feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Opslag"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index d6e26314a0f9..ed202fae1b7a 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ପ୍ରତିବନ୍ଧିତ ସେଟିଂ ଦ୍ୱାରା ନିୟନ୍ତ୍ରଣ କରାଯାଇଛି"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"କଲ କରିବାବେଳେ ଉପଲବ୍ଧ ନଥାଏ"</string>
<string name="disabled" msgid="8017887509554714950">"ଅକ୍ଷମ ହୋଇଛି"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ଅନୁମତି ଦିଆଯାଇଛି"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"ଅନୁମତି ନାହିଁ"</string>
<string name="install_other_apps" msgid="3232595082023199454">"ଅଜଣା ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
@@ -612,7 +611,7 @@
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ଏହି ଫୋନ୍"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
<string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ଆନାଲଗ"</string>
- <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ଅକ୍ସିଲାରି"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ଏହି ଡିଭାଇସରେ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ସ୍ୱିଚ କରିବା ପାଇଁ ଆକାଉଣ୍ଟକୁ ଅପଗ୍ରେଡ କରନ୍ତୁ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ଏଠାରେ ଡାଉନଲୋଡଗୁଡ଼ିକୁ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ବିଲ୍ଟ-ଇନ ସ୍ପିକର"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ଟିଭି ଅଡିଓ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ସଂଯୋଗ କରିବାରେ ସମସ୍ୟା ହେଉଛି। ଡିଭାଇସ୍ ବନ୍ଦ କରି ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ତାରଯୁକ୍ତ ଅଡିଓ ଡିଭାଇସ୍"</string>
<string name="help_label" msgid="3528360748637781274">"ସାହାଯ୍ୟ ଓ ମତାମତ"</string>
<string name="storage_category" msgid="2287342585424631813">"ଷ୍ଟୋରେଜ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ab5f4afd07f3..ee0f761e00f0 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ਪ੍ਰਤਿਬੰਧਿਤ ਸੈਟਿੰਗ ਰਾਹੀਂ ਕੰਟਰੋਲ ਕੀਤੀ ਜਾਂਦੀ ਹੈ"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ਕਾਲਾਂ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="disabled" msgid="8017887509554714950">"ਅਯੋਗ ਬਣਾਇਆ"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"ਚਾਲੂ ਹੈ"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
<string name="install_other_apps" msgid="3232595082023199454">"ਅਗਿਆਤ ਐਪਾਂ ਦੀ ਸਥਾਪਨਾ"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ਬਿਲਟ-ਇਨ ਸਪੀਕਰ"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ਟੀਵੀ ਆਡੀਓ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ। ਡੀਵਾਈਸ ਨੂੰ ਬੰਦ ਕਰਕੇ ਵਾਪਸ ਚਾਲੂ ਕਰੋ"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ਤਾਰ ਵਾਲਾ ਆਡੀਓ ਡੀਵਾਈਸ"</string>
<string name="help_label" msgid="3528360748637781274">"ਮਦਦ ਅਤੇ ਵਿਚਾਰ"</string>
<string name="storage_category" msgid="2287342585424631813">"ਸਟੋਰੇਜ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 462142468e26..fec5bf1469d8 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Obowiązują ustawienia z ograniczonym dostępem"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Niedostępne w trakcie połączeń"</string>
<string name="disabled" msgid="8017887509554714950">"Wyłączona"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Włączono"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Dozwolone"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Niedozwolone"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalowanie nieznanych aplikacji"</string>
@@ -626,8 +625,10 @@
<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_internal_speakers" msgid="4662765121700213785">"Wbudowany głośnik"</string>
- <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Telewizyjne urządzenie audio"</string>
+ <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio z telewizora"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Przewodowe urządzenie audio"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoc i opinie"</string>
<string name="storage_category" msgid="2287342585424631813">"Pamięć wewnętrzna"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 482f47931f4a..62d879b8e663 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante ligações"</string>
<string name="disabled" msgid="8017887509554714950">"Desativado"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Ativado"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidos"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Alto-falante integrado"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index d6ac53390403..3486037ba240 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -610,7 +610,7 @@
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo associado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
<string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
- <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógica"</string>
<string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Atualize a conta para mudar"</string>
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altifalante integrado"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 482f47931f4a..62d879b8e663 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante ligações"</string>
<string name="disabled" msgid="8017887509554714950">"Desativado"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Ativado"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidos"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Alto-falante integrado"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 757fee9e110e..8965a0cfdd2f 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlată de setarea restricționată"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponibil în timpul apelurilor"</string>
<string name="disabled" msgid="8017887509554714950">"Dezactivată"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Activată"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Permise"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nepermise"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalarea aplicațiilor necunoscute"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Difuzor încorporat"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problemă la conectare. Oprește și repornește dispozitivul."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispozitiv audio cu fir"</string>
<string name="help_label" msgid="3528360748637781274">"Ajutor și feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Stocare"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 9e922a0b85b3..2da67085adf6 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролируется настройками с ограниченным доступом"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно во время вызовов"</string>
<string name="disabled" msgid="8017887509554714950">"Отключено"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Включено"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Разрешено"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Запрещено"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Установка неизвестных приложений"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Встроенный динамик"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудиовыход телевизора"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ошибка подключения. Выключите и снова включите устройство."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Проводное аудиоустройство"</string>
<string name="help_label" msgid="3528360748637781274">"Справка/отзыв"</string>
<string name="storage_category" msgid="2287342585424631813">"Хранилище"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 517b00c61efb..1c57acd16887 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"සීමා කළ සැකසීම මගින් පාලනය වේ"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ඇමතුම් අතරතුර නොපවතී"</string>
<string name="disabled" msgid="8017887509554714950">"අබල කර ඇත"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"සබලයි"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ඉඩ දුන්"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"ඉඩ නොදෙන"</string>
<string name="install_other_apps" msgid="3232595082023199454">"නොදන්නා යෙදුම් ස්ථාපනය"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"එකට තැනූ ශබ්දවාහිනීය"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"රූපවාහිනී ශ්‍රව්‍ය"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"සම්බන්ධ කිරීමේ ගැටලුවකි උපාංගය ක්‍රියාවිරහිත කර &amp; ආපසු ක්‍රියාත්මක කරන්න"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"රැහැන්ගත කළ ඕඩියෝ උපාංගය"</string>
<string name="help_label" msgid="3528360748637781274">"උදවු &amp; ප්‍රතිපෝෂණ"</string>
<string name="storage_category" msgid="2287342585424631813">"ගබඩාව"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e8fb53fdcef6..5534ed081057 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ovládané obmedzeným nastavením"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Počas hovorov nie je k dispozícii"</string>
<string name="disabled" msgid="8017887509554714950">"Deaktivované"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Zapnuté"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Povolené"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nie je povolené"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Inštalácia neznámych aplikácií"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vstavaný reproduktor"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk televízora"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Priestor"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index bae7722cc6e9..be7b11587468 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vgrajen zvočnik"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvok televizorja"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Shramba"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 8a711d5ebcee..06da1722ad75 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollohet nga \"Cilësimet e kufizuara\""</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nuk ofrohet gjatë telefonatave"</string>
<string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aktivizuar"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Lejohet"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Nuk lejohet"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Instalo aplikacione të panjohura"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altoparlanti i integruar"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audioja e televizorit"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem me lidhjen. Fike dhe ndize përsëri pajisjen"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Pajisja audio me tel"</string>
<string name="help_label" msgid="3528360748637781274">"Ndihma dhe komentet"</string>
<string name="storage_category" msgid="2287342585424631813">"Hapësira ruajtëse"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index d57eb5c4c830..63d1502c7809 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно током позива"</string>
<string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Омогућено"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Дозвољено"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Није дозвољено"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознатих апликација"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Уграђени звучник"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Звук ТВ-а"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
<string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
<string name="storage_category" msgid="2287342585424631813">"Меморијски простор"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 5d27839daa6a..131cca795bb2 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styrs av spärrad inställning"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ej tillgänglig under samtal"</string>
<string name="disabled" msgid="8017887509554714950">"Inaktiverad"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Aktiverat"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Tillåts"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Tillåts inte"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Installera okända appar"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Inbyggd högtalare"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tv-ljud"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
<string name="help_label" msgid="3528360748637781274">"Hjälp och feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Lagring"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 9ddb7ff129ad..1cb95a7ccde6 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Imedhibitiwa na Mpangilio wenye Mipaka"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Haipatikani wakati unaongea kwa simu"</string>
<string name="disabled" msgid="8017887509554714950">"Imezimwa"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Imewashwa"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Imeruhusiwa"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Hairuhusiwi"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Kuweka programu zisizojulikana"</string>
@@ -625,9 +624,11 @@
<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_internal_speakers" msgid="4662765121700213785">"Spika iliyojumuishwa ndani"</string>
+ <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Spika iliyojumuishwa"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sauti ya Televisheni"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kuna tatizo la kuunganisha kwenye Intaneti. Zima kisha uwashe kifaa"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Hifadhi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 68a60cf85a90..cc8a36fac3ce 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"வரையறுக்கப்பட்ட அமைப்பால் கட்டுப்படுத்தப்படுகிறது"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"அழைப்புகளின்போது பயன்படுத்த முடியாது"</string>
<string name="disabled" msgid="8017887509554714950">"முடக்கப்பட்டது"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"இயக்கப்பட்டது"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"அனுமதிக்கப்பட்டது"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"அனுமதிக்கப்படவில்லை"</string>
<string name="install_other_apps" msgid="3232595082023199454">"தெரியாத ஆப்ஸ்களை நிறுவுதல்"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"உள்ளமைந்த ஸ்பீக்கர்"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"டிவி ஆடியோ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"இணைப்பதில் சிக்கல். சாதனத்தை ஆஃப் செய்து மீண்டும் ஆன் செய்யவும்"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"வயருடன்கூடிய ஆடியோ சாதனம்"</string>
<string name="help_label" msgid="3528360748637781274">"உதவியும் கருத்தும்"</string>
<string name="storage_category" msgid="2287342585424631813">"சேமிப்பகம்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index c2f284e0acb6..ccb5aa8cd140 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"బిల్ట్-ఇన్ స్పీకర్"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"టీవీ ఆడియో"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
<string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
<string name="storage_category" msgid="2287342585424631813">"స్టోరేజ్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 035644f845f1..08d2017e8418 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ควบคุมโดยการตั้งค่าที่จำกัด"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ใช้งานไม่ได้ขณะสนทนาโทรศัพท์"</string>
<string name="disabled" msgid="8017887509554714950">"ปิดอยู่"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"เปิดใช้อยู่"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"อนุญาต"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"ไม่อนุญาต"</string>
<string name="install_other_apps" msgid="3232595082023199454">"ติดตั้งแอปที่ไม่รู้จัก"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ลำโพงในตัว"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"เสียงจากทีวี"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"เกิดปัญหาในการเชื่อมต่อ ปิดอุปกรณ์แล้วเปิดใหม่อีกครั้ง"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"อุปกรณ์เสียงแบบมีสาย"</string>
<string name="help_label" msgid="3528360748637781274">"ความช่วยเหลือและความคิดเห็น"</string>
<string name="storage_category" msgid="2287342585424631813">"พื้นที่เก็บข้อมูล"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4ef2f436898a..14069b9db21d 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kinokontrol ng Pinaghihigpitang Setting"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Hindi available habang may tawag"</string>
<string name="disabled" msgid="8017887509554714950">"Naka-disable"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Naka-enable"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Pinapayagan"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Hindi pinapayagan"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Mag-install ng di-kilalang app"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in na speaker"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio ng TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Nagkaproblema sa pagkonekta. I-off at pagkatapos ay i-on ang device"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
<string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
<string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 19295aa169ef..70210030d7a9 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kısıtlanmış ayar tarafından kontrol ediliyor"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Telefon aramaları sırasında kullanılamaz"</string>
<string name="disabled" msgid="8017887509554714950">"Devre dışı"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Etkin"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"İzin verildi"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"İzin verilmiyor"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Bilinmeyen uygulamaları yükleme"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Dahili hoparlör"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Sesi"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Bağlanırken sorun oluştu. Cihazı kapatıp tekrar açın"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Depolama"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index e46137fd237e..e8fb02e1ee82 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Керується налаштуваннями з обмеженнями"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно під час викликів"</string>
<string name="disabled" msgid="8017887509554714950">"Вимкнено"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Увімкнено"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Дозволено"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Заборонено"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Встановлювати невідомі додатки"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вбудований динамік"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудіо з телевізора"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
<string name="help_label" msgid="3528360748637781274">"Довідка й відгуки"</string>
<string name="storage_category" msgid="2287342585424631813">"Сховище"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index e4b4001352cd..a0ff95a579b0 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"پہلے سے شامل اسپیکر"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"‏‫TV آڈیو"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"منسلک کرنے میں مسئلہ پیش آ گیا۔ آلہ کو آف اور بیک آن کریں"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"وائرڈ آڈیو آلہ"</string>
<string name="help_label" msgid="3528360748637781274">"مدد اور تاثرات"</string>
<string name="storage_category" msgid="2287342585424631813">"اسٹوریج"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 2608a0440804..0a6588511647 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -627,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ichki karnay"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
<string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
<string name="storage_category" msgid="2287342585424631813">"Xotira"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 8f5c0c2675e4..5e1e3dad0034 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Do chế độ Cài đặt hạn chế kiểm soát"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Không dùng được khi có cuộc gọi"</string>
<string name="disabled" msgid="8017887509554714950">"Đã tắt"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Đã bật"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Được phép"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Không được phép"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Cài ứng dụng không rõ nguồn"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Loa tích hợp"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Âm thanh TV"</string>
<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>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<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>
<string name="storage_category" msgid="2287342585424631813">"Bộ nhớ"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 85d3c179a623..6bf27b35d4fe 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限设置控制"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通话期间无法使用"</string>
<string name="disabled" msgid="8017887509554714950">"已停用"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"已启用"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"允许"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"不允许"</string>
<string name="install_other_apps" msgid="3232595082023199454">"安装未知应用"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"内置扬声器"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"电视音频"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"连接时遇到问题。请关闭并重新开启设备"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有线音频设备"</string>
<string name="help_label" msgid="3528360748637781274">"帮助和反馈"</string>
<string name="storage_category" msgid="2287342585424631813">"存储空间"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 3ff554000a6c..9f96b5bf44b1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由「受限設定」控制"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話時無法使用"</string>
<string name="disabled" msgid="8017887509554714950">"已停用"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"已啟用"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
<string name="install_other_apps" msgid="3232595082023199454">"安裝不明的應用程式"</string>
@@ -602,7 +601,7 @@
<string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string>
<string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(沒有名稱)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
- <string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string>
+ <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>
<string name="media_transfer_this_device_name_tv" msgid="8508713779441163887">"這部電視"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"內置喇叭"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"電視音訊"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連接,請關閉裝置然後重新開機"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音響裝置"</string>
<string name="help_label" msgid="3528360748637781274">"說明與意見反映"</string>
<string name="storage_category" msgid="2287342585424631813">"儲存空間"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 5362d380564f..e5f29e904e0a 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限制的設定控管"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話時無法使用"</string>
<string name="disabled" msgid="8017887509554714950">"已停用"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"已啟用"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
<string name="install_other_apps" msgid="3232595082023199454">"安裝不明應用程式"</string>
@@ -628,6 +627,8 @@
<string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"內建喇叭"</string>
<string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"電視音訊"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連線,請關閉裝置後再重新開啟"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音訊裝置"</string>
<string name="help_label" msgid="3528360748637781274">"說明與意見回饋"</string>
<string name="storage_category" msgid="2287342585424631813">"儲存空間"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 79ce6d7b25d0..c587678056e8 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -539,8 +539,7 @@
<string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kulawulwe Isethingi Elikhawulelwe"</string>
<string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Akutholakali ngesikhathi samakholi"</string>
<string name="disabled" msgid="8017887509554714950">"Akusebenzi"</string>
- <!-- no translation found for enabled (3997122818554810678) -->
- <skip />
+ <string name="enabled" msgid="3997122818554810678">"Ukwenza kusebenze"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"Kuvumelekile"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"Akuvumelekile"</string>
<string name="install_other_apps" msgid="3232595082023199454">"Faka ama-app angaziwa"</string>
@@ -626,8 +625,10 @@
<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_internal_speakers" msgid="4662765121700213785">"Isipikha esakhelwe ngaphakathi"</string>
- <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Umsondo weTV"</string>
+ <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Umsindo we-TV"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Inkinga yokuxhumeka. Vala idivayisi futhi uphinde uyivule"</string>
+ <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+ <skip />
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Idivayisi yomsindo enentambo"</string>
<string name="help_label" msgid="3528360748637781274">"Usizo nempendulo"</string>
<string name="storage_category" msgid="2287342585424631813">"Isitoreji"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 129949fd38b2..7f4544379cd3 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -429,6 +429,7 @@ android_library {
manifest: "AndroidManifest-res.xml",
flags_packages: [
"android.app.flags-aconfig",
+ "com_android_systemui_flags",
],
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 436e92bc0efa..83eb9631f1e3 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -525,6 +525,14 @@ flag {
}
flag {
+ name: "status_bar_font_updates"
+ namespace: "systemui"
+ description: "Read only flag for using a new font in the status bar"
+ bug: "393609116"
+ is_fixed_read_only: true
+}
+
+flag {
name: "promote_notifications_automatically"
namespace: "systemui"
description: "Flag to automatically turn certain notifications into promoted notifications so "
@@ -1436,16 +1444,6 @@ flag {
}
flag {
- name: "dozeui_scheduling_alarms_background_execution"
- namespace: "systemui"
- description: "Decide whether to execute binder calls to schedule alarms in background thread"
- bug: "330492575"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "media_lockscreen_launch_animation"
namespace : "systemui"
description : "Enable the origin launch animation for UMO when opening on top of lockscreen."
@@ -1858,6 +1856,13 @@ flag {
}
flag {
+ name: "shade_header_fonts"
+ namespace: "systemui"
+ description: "Updates the fonts of the shade header"
+ bug: "393609724"
+}
+
+flag {
name: "keyboard_shortcut_helper_shortcut_customizer"
namespace: "systemui"
description: "An implementation of shortcut customizations through shortcut helper."
@@ -2134,7 +2139,7 @@ flag {
name: "media_projection_grey_error_text"
namespace: "systemui"
description: "Set the error text color to grey when app sharing is hidden by the requesting app"
- bug: "390624334"
+ bug: "400877402"
metadata {
purpose: PURPOSE_BUGFIX
}
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 7ee6a6e5ebf4..5599db7689c2 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -1216,6 +1216,13 @@ constructor(
private var animation: TransitionAnimator.Animation? = null
/**
+ * Whether the opening/closing window needs to reparented to the view's window at the
+ * beginning of the animation. Since we don't always do this, we need to keep track of it in
+ * order to have the rest of the animation behave correctly.
+ */
+ var reparent = false
+
+ /**
* A timeout to cancel the transition animation if the remote animation is not started or
* cancelled within [TRANSITION_TIMEOUT] milliseconds after the intent was started.
*
@@ -1469,6 +1476,17 @@ constructor(
transitionAnimator.isExpandingFullyAbove(controller.transitionContainer, endState)
val windowState = startingWindowState ?: controller.windowAnimatorState
+ // We only reparent launch animations. In current integrations, returns are
+ // not affected by the issue solved by reparenting, and they present
+ // additional problems when the view lives in the Status Bar.
+ // TODO(b/397646693): remove this exception.
+ val isEligibleForReparenting = controller.isLaunching
+ val viewRoot = controller.transitionContainer.viewRootImpl
+ val skipReparenting = skipReparentTransaction || viewRoot == null
+ if (moveTransitionAnimationLayer() && isEligibleForReparenting && !skipReparenting) {
+ reparent = true
+ }
+
// We animate the opening window and delegate the view expansion to [this.controller].
val delegate = this.controller
val controller =
@@ -1536,16 +1554,13 @@ constructor(
)
}
- if (moveTransitionAnimationLayer() && !skipReparentTransaction) {
+ if (reparent) {
// Ensure that the launching window is rendered above the view's window,
// so it is not obstructed.
// TODO(b/397180418): re-use the start transaction once the
// RemoteAnimation wrapper is cleaned up.
SurfaceControl.Transaction().use {
- it.reparent(
- window.leash,
- controller.transitionContainer.viewRootImpl.surfaceControl,
- )
+ it.reparent(window.leash, viewRoot.surfaceControl)
it.apply()
}
}
@@ -1603,7 +1618,7 @@ constructor(
null
}
val fadeWindowBackgroundLayer =
- if (moveTransitionAnimationLayer()) {
+ if (reparent) {
false
} else {
!controller.isBelowAnimatingWindow
@@ -1727,7 +1742,7 @@ constructor(
// fade in progressively. Otherwise, it should be fully opaque and will be progressively
// revealed as the window background color layer above the window fades out.
val alpha =
- if (moveTransitionAnimationLayer() || controller.isBelowAnimatingWindow) {
+ if (reparent || controller.isBelowAnimatingWindow) {
if (controller.isLaunching) {
interpolators.contentAfterFadeInInterpolator.getInterpolation(
windowProgress
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
index 21ec89646f0f..060f0c94732d 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
@@ -197,6 +197,10 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner
// Release surface references now. This is apparently to free GPU memory
// before GC would.
info.releaseAllSurfaces();
+ // Make sure that the transition leashes created are not leaked.
+ for (SurfaceControl leash : leashMap.values()) {
+ finishTransaction.reparent(leash, null);
+ }
// Don't release here since launcher might still be using them. Instead
// let launcher release them (eg. via RemoteAnimationTargets)
leashMap.clear();
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
index df50eb8fa3e8..da07fbd9b6a6 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
@@ -101,10 +101,17 @@ fun PlatformIconButton(
modifier: Modifier = Modifier,
enabled: Boolean = true,
colors: IconButtonColors = iconButtonColors(),
+ shape: Shape = IconButtonDefaults.standardShape,
@DrawableRes iconResource: Int,
contentDescription: String?,
) {
- IconButton(modifier = modifier, onClick = onClick, enabled = enabled, colors = colors) {
+ IconButton(
+ modifier = modifier,
+ onClick = onClick,
+ enabled = enabled,
+ colors = colors,
+ shape = shape,
+ ) {
Icon(
painter = painterResource(id = iconResource),
contentDescription = contentDescription,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
index 2530a4f240e3..54232e76a568 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
@@ -134,6 +134,7 @@ private class NestedScrollControllerNode(
private var bounds: NestedScrollableBound,
) : DelegatingNode(), NestedScrollConnection {
private var childrenConsumedAnyScroll = false
+ private var availableOnPreScroll = Offset.Zero
init {
delegate(nestedScrollModifierNode(this, dispatcher = null))
@@ -153,12 +154,21 @@ private class NestedScrollControllerNode(
this.bounds = bounds
}
+ override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+ availableOnPreScroll = available
+ return Offset.Zero
+ }
+
override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource,
): Offset {
- if (hasConsumedScrollInBounds(consumed.x) || hasConsumedScrollInBounds(consumed.y)) {
+ val consumedIncludingPreScroll = availableOnPreScroll - available
+ if (
+ hasConsumedScrollInBounds(consumedIncludingPreScroll.x) ||
+ hasConsumedScrollInBounds(consumedIncludingPreScroll.y)
+ ) {
childrenConsumedAnyScroll = true
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/OffsetOverscrollEffect.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/OffsetOverscrollEffect.kt
index 1bb8ae5019fb..07a571b94ce4 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/OffsetOverscrollEffect.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/OffsetOverscrollEffect.kt
@@ -16,7 +16,6 @@
package com.android.compose.gesture.effect
-import androidx.annotation.VisibleForTesting
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.foundation.OverscrollEffect
import androidx.compose.foundation.OverscrollFactory
@@ -94,7 +93,6 @@ class OffsetOverscrollEffect(animationScope: CoroutineScope, animationSpec: Anim
companion object {
private val MaxDistance = 400.dp
- @VisibleForTesting
fun computeOffset(density: Density, overscrollDistance: Float): Int {
val maxDistancePx = with(density) { MaxDistance.toPx() }
val progress = ProgressConverter.Default.convert(overscrollDistance / maxDistancePx)
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
index 84370ed4d2c7..6fb3679dfb7c 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
@@ -43,7 +43,7 @@ fun PlatformTheme(isDarkTheme: Boolean = isSystemInDarkTheme(), content: @Compos
val context = LocalContext.current
val colorScheme = remember(context, isDarkTheme) { platformColorScheme(isDarkTheme, context) }
- val androidColorScheme = remember(context) { AndroidColorScheme(context) }
+ val androidColorScheme = remember(context, isDarkTheme) { AndroidColorScheme(context) }
val typefaceNames = remember(context) { TypefaceNames.get(context) }
val typefaceTokens = remember(typefaceNames) { TypefaceTokens(typefaceNames) }
val typography =
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
index 424af3395913..377cbe238f49 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
@@ -23,9 +23,13 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performTouchInput
@@ -103,4 +107,35 @@ class NestedScrollControllerTest {
rule.waitForIdle()
assertThat(state.isOuterScrollAllowed).isTrue()
}
+
+ @Test
+ fun supportsPreScrolls() {
+ val state = NestedScrollControlState()
+ rule.setContent {
+ Box(
+ Modifier.fillMaxSize()
+ .nestedScrollController(state)
+ .nestedScroll(
+ remember {
+ object : NestedScrollConnection {
+ override fun onPreScroll(
+ available: Offset,
+ source: NestedScrollSource,
+ ): Offset = available
+ }
+ }
+ )
+ .scrollable(rememberScrollableState { 0f }, Orientation.Vertical)
+ )
+ }
+
+ rule.onRoot().performTouchInput {
+ down(topLeft)
+ moveBy(Offset(0f, bottom))
+ }
+ assertThat(state.isOuterScrollAllowed).isFalse()
+
+ rule.onRoot().performTouchInput { up() }
+ assertThat(state.isOuterScrollAllowed).isTrue()
+ }
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
index d9e8f02f005b..52b1e3aeb00c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
@@ -30,9 +30,11 @@ import androidx.compose.animation.scaleOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
@@ -42,7 +44,6 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
@@ -154,9 +155,7 @@ fun ColumnVolumeSliders(
totalCount = viewModels.size,
),
)
- .thenIf(!Flags.volumeRedesign()) {
- Modifier.padding(top = 16.dp)
- },
+ .padding(top = if (Flags.volumeRedesign()) 4.dp else 16.dp),
state = sliderState,
onValueChange = { newValue: Float ->
sliderViewModel.onValueChanged(sliderState, newValue)
@@ -223,7 +222,7 @@ private fun ExpandButtonLegacy(
}
@Composable
-private fun ExpandButton(
+private fun RowScope.ExpandButton(
isExpanded: Boolean,
isExpandable: Boolean,
onExpandedChanged: (Boolean) -> Unit,
@@ -243,16 +242,17 @@ private fun ExpandButton(
) {
PlatformIconButton(
modifier =
- Modifier.size(width = 48.dp, height = 40.dp).semantics {
+ Modifier.size(40.dp).semantics {
role = Role.Switch
stateDescription = expandButtonStateDescription
},
onClick = { onExpandedChanged(!isExpanded) },
colors =
IconButtonDefaults.iconButtonColors(
- containerColor = Color.Transparent,
- contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
+ containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
+ contentColor = MaterialTheme.colorScheme.onSurface,
),
+ shape = RoundedCornerShape(12.dp),
iconResource =
if (isExpanded) {
R.drawable.ic_arrow_down_24dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index da54cb8e4679..f9492dad85df 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -30,14 +30,16 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon as MaterialIcon
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -58,31 +60,33 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.disabled
import androidx.compose.ui.semantics.progressBarRangeInfo
-import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.setProgress
import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import com.android.compose.PlatformSlider
import com.android.compose.PlatformSliderColors
import com.android.systemui.Flags
-import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Icon as IconModel
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.res.R
+import com.android.systemui.volume.dialog.sliders.ui.compose.SliderTrack
import com.android.systemui.volume.haptics.ui.VolumeHapticsConfigsProvider
import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState
-import com.android.systemui.volume.ui.slider.AccessibilityParams
-import com.android.systemui.volume.ui.slider.Haptics
-import com.android.systemui.volume.ui.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.AccessibilityParams
+import com.android.systemui.volume.ui.compose.slider.Haptics
+import com.android.systemui.volume.ui.compose.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.SliderIcon
import kotlin.math.round
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun VolumeSlider(
state: SliderState,
@@ -92,7 +96,7 @@ fun VolumeSlider(
modifier: Modifier = Modifier,
hapticsViewModelFactory: SliderHapticsViewModel.Factory?,
onValueChangeFinished: (() -> Unit)? = null,
- button: (@Composable () -> Unit)? = null,
+ button: (@Composable RowScope.() -> Unit)? = null,
) {
if (!Flags.volumeRedesign()) {
LegacyVolumeSlider(
@@ -107,54 +111,86 @@ fun VolumeSlider(
return
}
- Column(
- modifier = modifier.animateContentSize().semantics(true) {},
- verticalArrangement = Arrangement.Top,
- ) {
+ Column(modifier = modifier.animateContentSize()) {
+ Text(
+ text = state.label,
+ style = MaterialTheme.typography.titleMedium,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = Modifier.fillMaxWidth().clearAndSetSemantics {},
+ )
Row(
- horizontalArrangement = Arrangement.spacedBy(12.dp),
- modifier = Modifier.fillMaxWidth().height(40.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
- state.icon?.let {
- Icon(
- icon = it,
- tint = MaterialTheme.colorScheme.onSurface,
- modifier = Modifier.size(24.dp),
+ val materialSliderColors =
+ SliderDefaults.colors(
+ activeTickColor = MaterialTheme.colorScheme.surfaceContainerHigh,
+ inactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHigh,
)
- }
- Text(
- text = state.label,
- style = MaterialTheme.typography.titleMedium,
- color = MaterialTheme.colorScheme.onSurface,
- modifier = Modifier.weight(1f).clearAndSetSemantics {},
+ Slider(
+ value = state.value,
+ valueRange = state.valueRange,
+ onValueChanged = onValueChange,
+ onValueChangeFinished = { onValueChangeFinished?.invoke() },
+ colors = materialSliderColors,
+ isEnabled = state.isEnabled,
+ stepDistance = state.step,
+ accessibilityParams =
+ AccessibilityParams(
+ contentDescription = state.a11yContentDescription,
+ stateDescription = state.a11yStateDescription,
+ ),
+ track = { sliderState ->
+ SliderTrack(
+ sliderState = sliderState,
+ colors = materialSliderColors,
+ isEnabled = state.isEnabled,
+ activeTrackStartIcon =
+ state.icon?.let { icon ->
+ { iconsState ->
+ SliderIcon(
+ icon = {
+ Icon(icon = icon, modifier = Modifier.size(24.dp))
+ },
+ isVisible = iconsState.isActiveTrackStartIconVisible,
+ )
+ }
+ },
+ inactiveTrackStartIcon =
+ state.icon?.let { icon ->
+ { iconsState ->
+ SliderIcon(
+ icon = {
+ Icon(icon = icon, modifier = Modifier.size(24.dp))
+ },
+ isVisible = !iconsState.isActiveTrackStartIconVisible,
+ )
+ }
+ },
+ )
+ },
+ thumb = { sliderState, interactionSource ->
+ SliderDefaults.Thumb(
+ sliderState = sliderState,
+ interactionSource = interactionSource,
+ enabled = state.isEnabled,
+ colors = materialSliderColors,
+ thumbSize = DpSize(4.dp, 52.dp),
+ )
+ },
+ haptics =
+ hapticsViewModelFactory?.let {
+ Haptics.Enabled(
+ hapticsViewModelFactory = it,
+ hapticFilter = state.hapticFilter,
+ orientation = Orientation.Horizontal,
+ )
+ } ?: Haptics.Disabled,
+ modifier = Modifier.weight(1f).sysuiResTag(state.label),
)
- button?.invoke()
+ button?.invoke(this)
}
-
- Slider(
- value = state.value,
- valueRange = state.valueRange,
- onValueChanged = onValueChange,
- onValueChangeFinished = { onValueChangeFinished?.invoke() },
- isEnabled = state.isEnabled,
- stepDistance = state.step,
- accessibilityParams =
- AccessibilityParams(
- contentDescription = state.a11yContentDescription,
- stateDescription = state.a11yStateDescription,
- ),
- haptics =
- hapticsViewModelFactory?.let {
- Haptics.Enabled(
- hapticsViewModelFactory = it,
- hapticFilter = state.hapticFilter,
- orientation = Orientation.Horizontal,
- )
- } ?: Haptics.Disabled,
- modifier =
- Modifier.height(40.dp).padding(top = 4.dp, bottom = 12.dp).sysuiResTag(state.label),
- )
state.disabledMessage?.let { disabledMessage ->
AnimatedVisibility(visible = !state.isEnabled) {
Row(
@@ -253,7 +289,11 @@ private fun LegacyVolumeSlider(
enabled = state.isEnabled,
icon = {
state.icon?.let {
- SliderIcon(icon = it, onIconTapped = onIconTapped, isTappable = state.isMutable)
+ LegacySliderIcon(
+ icon = it,
+ onIconTapped = onIconTapped,
+ isTappable = state.isMutable,
+ )
}
},
colors = sliderColors,
@@ -289,8 +329,8 @@ private fun valueState(state: SliderState): State<Float> {
}
@Composable
-private fun SliderIcon(
- icon: Icon,
+private fun LegacySliderIcon(
+ icon: IconModel,
onIconTapped: () -> Unit,
isTappable: Boolean,
modifier: Modifier = Modifier,
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
index 96c3ac75587e..8744357a74c9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
@@ -144,23 +144,25 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController
listOf(
GSFAxes.WEIGHT.toClockAxis(
type = AxisType.Float,
- currentValue = 475f,
+ currentValue = 400f,
name = "Weight",
description = "Glyph Weight",
),
GSFAxes.WIDTH.toClockAxis(
type = AxisType.Float,
- currentValue = 85f,
+ currentValue = 80f,
name = "Width",
description = "Glyph Width",
),
GSFAxes.ROUND.toClockAxis(
type = AxisType.Boolean,
+ currentValue = 100f,
name = "Round",
description = "Glyph Roundness",
),
GSFAxes.SLANT.toClockAxis(
type = AxisType.Boolean,
+ currentValue = 0f,
name = "Slant",
description = "Glyph Slant",
),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 859137507bbf..358635e2400c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -80,17 +80,18 @@ class DisplayRepositoryTest : SysuiTestCase() {
testScope.backgroundScope,
UnconfinedTestDispatcher(),
)
- DisplayRepositoryImpl(
+ val displaysWithDecorRepository =
+ DisplaysWithDecorationsRepositoryImpl(
commandQueue,
windowManager,
testScope.backgroundScope,
displayRepositoryFromLib,
)
- .also {
- verify(displayManager, never()).registerDisplayListener(any(), any())
- // It needs to be called, just once, for the initial value.
- verify(displayManager).getDisplays()
- }
+ DisplayRepositoryImpl(displayRepositoryFromLib, displaysWithDecorRepository).also {
+ verify(displayManager, never()).registerDisplayListener(any(), any())
+ // It needs to be called, just once, for the initial value.
+ verify(displayManager).getDisplays()
+ }
}
@Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt
index da7a723f220e..8afaea32273d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt
@@ -16,7 +16,6 @@
package com.android.systemui.display.data.repository
-import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -24,77 +23,41 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
-import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.isActive
import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
@RunWith(AndroidJUnit4::class)
@SmallTest
-class DisplayScopeRepositoryImplTest : SysuiTestCase() {
+class DisplayScopeRepositoryInstanceProviderTest : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
- private val fakeDisplayRepository = kosmos.displayRepository
- private val repo =
- DisplayScopeRepositoryImpl(
+ private val underTest =
+ DisplayScopeRepositoryInstanceProvider(
kosmos.applicationCoroutineScope,
kosmos.testDispatcher,
- fakeDisplayRepository,
)
- @Before
- fun setUp() {
- repo.start()
- }
-
- @Test
- fun scopeForDisplay_multipleCallsForSameDisplayId_returnsSameInstance() {
- val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
-
- assertThat(repo.scopeForDisplay(displayId = 1)).isSameInstanceAs(scopeForDisplay)
- }
-
- @Test
- fun scopeForDisplay_differentDisplayId_returnsNewInstance() {
- val scopeForDisplay1 = repo.scopeForDisplay(displayId = 1)
- val scopeForDisplay2 = repo.scopeForDisplay(displayId = 2)
-
- assertThat(scopeForDisplay1).isNotSameInstanceAs(scopeForDisplay2)
- }
-
@Test
- fun scopeForDisplay_activeByDefault() =
+ fun createInstance_activeByDefault() =
testScope.runTest {
- val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
+ val scopeForDisplay = underTest.createInstance(displayId = 1)
assertThat(scopeForDisplay.isActive).isTrue()
}
@Test
- fun scopeForDisplay_afterDisplayRemoved_scopeIsCancelled() =
+ fun destroyInstance_afterDisplayRemoved_scopeIsCancelled() =
testScope.runTest {
- val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
+ val scopeForDisplay = underTest.createInstance(displayId = 1)
- fakeDisplayRepository.removeDisplay(displayId = 1)
+ underTest.destroyInstance(scopeForDisplay)
assertThat(scopeForDisplay.isActive).isFalse()
}
-
- @Test
- fun scopeForDisplay_afterDisplayRemoved_returnsNewInstance() =
- testScope.runTest {
- val initialScope = repo.scopeForDisplay(displayId = 1)
-
- fakeDisplayRepository.removeDisplay(displayId = 1)
-
- val newScope = repo.scopeForDisplay(displayId = 1)
- assertThat(newScope).isNotSameInstanceAs(initialScope)
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
index 28b9e733be94..bf49d92dd2bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
@@ -44,9 +44,10 @@ class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() {
private val fakeDisplayRepository = kosmos.displayRepository
private val fakePerDisplayInstanceProviderWithTeardown =
kosmos.fakePerDisplayInstanceProviderWithTeardown
+ private val lifecycleManager = kosmos.fakeDisplayInstanceLifecycleManager
private val underTest: PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> =
- kosmos.fakePerDisplayInstanceRepository
+ kosmos.createPerDisplayInstanceRepository(overrideLifecycleManager = null)
@Before
fun addDisplays() = runBlocking {
@@ -109,6 +110,43 @@ class PerDisplayInstanceRepositoryImplTest : SysuiTestCase() {
verify(kosmos.dumpManager).registerNormalDumpable(anyString(), any())
}
+ @Test
+ fun perDisplay_afterCustomLifecycleManagerRemovesDisplay_destroyInstanceInvoked() =
+ testScope.runTest {
+ val underTest =
+ kosmos.createPerDisplayInstanceRepository(
+ overrideLifecycleManager = lifecycleManager
+ )
+ // Let's start with both
+ lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID)
+
+ val instance = underTest[NON_DEFAULT_DISPLAY_ID]
+
+ lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID)
+
+ // Now that the lifecycle manager says so, let's make sure it was destroyed
+ assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed)
+ .containsExactly(instance)
+ }
+
+ @Test
+ fun perDisplay_lifecycleManagerDoesNotContainIt_displayRepositoryDoes_returnsNull() =
+ testScope.runTest {
+ val underTest =
+ kosmos.createPerDisplayInstanceRepository(
+ overrideLifecycleManager = lifecycleManager
+ )
+ // only default display, so getting for the non-default one should fail, despite the
+ // repository having both displays already
+ lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID)
+
+ assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isNull()
+
+ lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID)
+
+ assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isNotNull()
+ }
+
private fun createDisplay(displayId: Int): Display =
display(type = Display.TYPE_INTERNAL, id = displayId)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
index 1d42424bc6ed..8d50cdc001ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
@@ -19,13 +19,17 @@ package com.android.systemui.qs.panels.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.FakeQSTile
import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.domain.interactor.disableDualShade
+import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -34,6 +38,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
+@EnableSceneContainer
class DetailsViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
private lateinit var underTest: DetailsViewModel
@@ -45,10 +50,12 @@ class DetailsViewModelTest : SysuiTestCase() {
underTest = kosmos.detailsViewModel
}
+ @OptIn(ExperimentalCoroutinesApi::class)
@Test
- fun changeTileDetailsViewModel() =
+ fun changeTileDetailsViewModelWithDualShadeEnabled() =
with(kosmos) {
testScope.runTest {
+ kosmos.enableDualShade()
val specs = listOf(spec, specNoDetails)
tileSpecRepository.setTiles(0, specs)
runCurrent()
@@ -85,4 +92,36 @@ class DetailsViewModelTest : SysuiTestCase() {
assertThat(underTest.onTileClicked(null)).isFalse()
}
}
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun ignoreChangingTileDetailsViewModelWithDualShadeDisabled() =
+ with(kosmos) {
+ testScope.runTest {
+ kosmos.disableDualShade()
+ val specs = listOf(spec, specNoDetails)
+ tileSpecRepository.setTiles(0, specs)
+ runCurrent()
+
+ val tiles = currentTilesInteractor.currentTiles.value
+
+ assertThat(currentTilesInteractor.currentTilesSpecs.size).isEqualTo(2)
+ assertThat(tiles[1].spec).isEqualTo(specNoDetails)
+ (tiles[1].tile as FakeQSTile).hasDetailsViewModel = false
+
+ assertThat(underTest.activeTileDetails).isNull()
+
+ // Click on the tile who has the `spec`.
+ assertThat(underTest.onTileClicked(spec)).isFalse()
+ assertThat(underTest.activeTileDetails).isNull()
+
+ // Click on a tile who dose not have a valid spec.
+ assertThat(underTest.onTileClicked(null)).isFalse()
+ assertThat(underTest.activeTileDetails).isNull()
+
+ // Click on a tile who dose not have a detailed view.
+ assertThat(underTest.onTileClicked(specNoDetails)).isFalse()
+ assertThat(underTest.activeTileDetails).isNull()
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationGroupingUtilTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationGroupingUtilTest.kt
index e04162bf990a..18f25cd4838b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationGroupingUtilTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationGroupingUtilTest.kt
@@ -16,24 +16,35 @@
package com.android.systemui.statusbar
+import android.app.Notification
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.collection.BundleEntry
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
class NotificationGroupingUtilTest(flags: FlagsParameterization) : SysuiTestCase() {
-
+ private val kosmos = testKosmos()
private lateinit var underTest: NotificationGroupingUtil
+ private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory
private lateinit var testHelper: NotificationTestHelper
companion object {
@@ -60,4 +71,55 @@ class NotificationGroupingUtilTest(flags: FlagsParameterization) : SysuiTestCase
underTest = NotificationGroupingUtil(row)
assertThat(underTest.showsTime(row)).isTrue()
}
+
+ @Test
+ fun iconExtractor_extractsSbn_notification() {
+ val row = testHelper.createRow()
+
+ underTest = NotificationGroupingUtil(row)
+
+ assertThat(NotificationGroupingUtil.ICON_EXTRACTOR.extractData(row)).isInstanceOf(
+ Notification::class.java)
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun iconExtractor_noException_bundle() {
+ val row = mock(ExpandableNotificationRow::class.java)
+ val be = BundleEntry("promotions")
+ `when`(row.entryAdapter).thenReturn(factory.create(be))
+
+ underTest = NotificationGroupingUtil(row)
+
+ assertThat(NotificationGroupingUtil.ICON_EXTRACTOR.extractData(row)).isNull()
+ }
+
+ @Test
+ fun iconComparator_sameNotificationIcon() {
+ val n1 = NotificationGroupingUtil.ICON_EXTRACTOR.extractData(testHelper.createRow())
+ val n2 = NotificationGroupingUtil.ICON_EXTRACTOR.extractData(testHelper.createRow())
+
+ assertThat(NotificationGroupingUtil.IconComparator().hasSameIcon(n1, n2)).isTrue()
+ }
+
+ @Test
+ fun iconComparator_differentNotificationIcon() {
+ val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_menu).build()
+ val n1 = NotificationGroupingUtil.ICON_EXTRACTOR.extractData(testHelper.createRow(notif))
+ val n2 = NotificationGroupingUtil.ICON_EXTRACTOR.extractData(testHelper.createRow())
+
+ assertThat(NotificationGroupingUtil.IconComparator().hasSameIcon(n1, n2)).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationBundleUi.FLAG_NAME)
+ fun iconComparator_bundleNotification() {
+ assertThat(NotificationGroupingUtil.IconComparator().hasSameIcon(null,
+ NotificationGroupingUtil.ICON_EXTRACTOR.extractData(testHelper.createRow()))).isFalse()
+ }
+
+ @Test
+ fun iconComparator_twoBundles() {
+ assertThat(NotificationGroupingUtil.IconComparator().hasSameIcon(null, null)).isFalse()
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 8120c2d9f816..6c498c8fd2f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -106,6 +106,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
@@ -117,6 +118,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
@@ -128,6 +130,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
@@ -152,6 +155,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
@@ -176,6 +180,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
@@ -200,6 +205,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isFalse()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index d921ab3b284d..a60e7c19d8bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -135,6 +135,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -157,6 +158,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -177,6 +179,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -215,6 +218,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -245,6 +249,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
// Only the projection info will show a timer
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index b5cfc7e9080d..8368fa671ea8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -842,6 +842,7 @@ class NotifChipsViewModelTest : SysuiTestCase() {
expectedContentDescriptionSubstrings: List<String> = emptyList(),
) {
val active = latest as OngoingActivityChipModel.Active
+ assertThat(active.isImportantForPrivacy).isFalse()
if (StatusBarConnectedDisplays.isEnabled) {
assertThat(active.icon)
.isInstanceOf(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
index 538247e26a6b..f8c57655005e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
@@ -87,7 +87,7 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ assertThat((latest as ScreenRecordChipModel.Recording).recordedTask).isNull()
}
@Test
@@ -99,7 +99,7 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen("host.package")
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ assertThat((latest as ScreenRecordChipModel.Recording).recordedTask).isNull()
}
@Test
@@ -116,7 +116,48 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
task,
)
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
+ assertThat((latest as ScreenRecordChipModel.Recording).recordedTask).isEqualTo(task)
+ }
+
+ @Test
+ fun screenRecordState_projectionIsNotProjecting_hostPackageNull() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ assertThat((latest as ScreenRecordChipModel.Recording).hostPackage).isNull()
+ }
+
+ @Test
+ fun screenRecordState_projectionIsEntireScreen_hostPackageMatches() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "host.package")
+
+ assertThat((latest as ScreenRecordChipModel.Recording).hostPackage)
+ .isEqualTo("host.package")
+ }
+
+ @Test
+ fun screenRecordState_projectionIsSingleTask_hostPackageMatches() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "host.package",
+ hostDeviceName = null,
+ task = createTask(taskId = 1),
+ )
+
+ assertThat((latest as ScreenRecordChipModel.Recording).hostPackage)
+ .isEqualTo("host.package")
}
@Test
@@ -150,7 +191,7 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
advanceTimeBy(901)
// THEN we automatically update to the recording state
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ assertThat(latest).isInstanceOf(ScreenRecordChipModel.Recording::class.java)
}
@Test
@@ -175,13 +216,14 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
)
// THEN we immediately switch to Recording, and we have the task
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
+ assertThat(latest).isInstanceOf(ScreenRecordChipModel.Recording::class.java)
+ assertThat((latest as ScreenRecordChipModel.Recording).recordedTask).isEqualTo(task)
// WHEN more than 900ms has elapsed
advanceTimeBy(200)
// THEN we still stay in the Recording state and we have the task
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
+ assertThat((latest as ScreenRecordChipModel.Recording).recordedTask).isEqualTo(task)
}
@Test
@@ -247,7 +289,7 @@ class ScreenRecordChipInteractorTest : SysuiTestCase() {
// THEN we *do* auto-start 400ms later
advanceTimeBy(401)
- assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ assertThat(latest).isInstanceOf(ScreenRecordChipModel.Recording::class.java)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index 005af366a6c0..91942213ce75 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -110,6 +110,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(400)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Countdown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
assertThat((latest as OngoingActivityChipModel.Active).icon).isNull()
assertThat((latest as OngoingActivityChipModel.Active).onClickListenerLegacy).isNull()
}
@@ -156,6 +157,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -261,6 +263,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
assertThat((latest as OngoingActivityChipModel.Active.Timer).startTimeMs)
.isEqualTo(1234)
@@ -275,6 +278,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
// THEN the start time is still the old start time
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
assertThat((latest as OngoingActivityChipModel.Active.Timer).startTimeMs)
.isEqualTo(1234)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index d6b10a89726e..99e378c78ee2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -384,6 +384,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.NoScreen(NORMAL_PACKAGE, hostDeviceName = null)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -407,6 +408,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
@@ -424,6 +426,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+ assertThat((latest as OngoingActivityChipModel.Active).isImportantForPrivacy).isTrue()
val icon =
(((latest as OngoingActivityChipModel.Active).icon)
as OngoingActivityChipModel.ChipIcon.SingleColorIcon)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
index 7135cf01394a..608a84bdb604 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
@@ -1159,6 +1159,11 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
.inOrder()
}
+ // The ranking between different chips should stay consistent between
+ // OngoingActivityChipsViewModel and PromotedNotificationsInteractor.
+ // Make sure to also change
+ // PromotedNotificationsInteractorTest#orderedChipNotificationKeys_rankingIsCorrect
+ // if you change this test.
@EnableChipsModernization
@Test
fun chips_screenRecordAndCallAndPromotedNotifs_secondNotifInOverflow() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
index 9faab58913f0..101874807474 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
@@ -127,7 +127,7 @@ class BundleEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isBubble() {
- assertThat(underTest.isBubbleCapable).isFalse()
+ assertThat(underTest.isBubble).isFalse()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
index 12ade62c3570..7449064bc65b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
@@ -110,7 +110,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getRow_adapter() {
- val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val row = mock(ExpandableNotificationRow::class.java)
val notification: Notification =
Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
@@ -128,7 +128,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isGroupRoot_adapter_groupSummary() {
- val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val row = mock(ExpandableNotificationRow::class.java)
val notification: Notification =
Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
@@ -175,7 +175,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun isClearable_adapter() {
- val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val row = mock(ExpandableNotificationRow::class.java)
val notification: Notification =
Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
@@ -193,7 +193,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getSummarization_adapter() {
- val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val row = mock(ExpandableNotificationRow::class.java)
val notification: Notification =
Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
@@ -213,7 +213,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun getIcons_adapter() {
- val row = Mockito.mock(ExpandableNotificationRow::class.java)
+ val row = mock(ExpandableNotificationRow::class.java)
val notification: Notification =
Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
@@ -258,7 +258,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
@Test
@EnableFlags(NotificationBundleUi.FLAG_NAME)
fun canDragAndDrop() {
- val pi = Mockito.mock(PendingIntent::class.java)
+ val pi = mock(PendingIntent::class.java)
Mockito.`when`(pi.isActivity).thenReturn(true)
val notification: Notification =
Notification.Builder(mContext, "")
@@ -284,7 +284,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
val entry = NotificationEntryBuilder().setNotification(notification).build()
underTest = factory.create(entry) as NotificationEntryAdapter
- assertThat(underTest.isBubbleCapable).isEqualTo(entry.isBubble)
+ assertThat(underTest.isBubble).isEqualTo(entry.isBubble)
}
@Test
@@ -350,7 +350,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
val notification: Notification =
Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
- .setFullScreenIntent(Mockito.mock(PendingIntent::class.java), true)
+ .setFullScreenIntent(mock(PendingIntent::class.java), true)
.build()
val entry =
@@ -399,7 +399,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
val notification: Notification =
Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
- .addAction(Mockito.mock(Notification.Action::class.java))
+ .addAction(mock(Notification.Action::class.java))
.build()
val entry = NotificationEntryBuilder().setNotification(notification).build()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
index ba2d40ba6a0d..3d7ced747450 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
+import android.app.Notification.FLAG_FOREGROUND_SERVICE
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Person
@@ -31,6 +32,10 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel
+import com.android.systemui.screenrecord.data.repository.screenRecordRepository
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.core.StatusBarRootModernization
@@ -169,6 +174,87 @@ class ColorizedFgsCoordinatorTest : SysuiTestCase() {
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ fun testIncludeScreenRecordNotifInSection_importanceDefault() =
+ kosmos.runTest {
+ // GIVEN a screen record event + screen record notif that has a status bar chip
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "screenRecord", promoted = false) {
+ setImportance(NotificationManager.IMPORTANCE_DEFAULT)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(promotedNotificationsInteractor.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|screenRecord|0")
+ .inOrder()
+
+ // THEN the entry is in the fgs section
+ assertTrue(sectioner.isInSection(screenRecordEntry))
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ fun testDiscludeScreenRecordNotifInSection_importanceMin() =
+ kosmos.runTest {
+ // GIVEN a screen record event + screen record notif that has a status bar chip
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "screenRecord", promoted = false) {
+ setImportance(NotificationManager.IMPORTANCE_MIN)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(promotedNotificationsInteractor.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|screenRecord|0")
+ .inOrder()
+
+ // THEN the entry is NOT in the fgs section
+ assertFalse(sectioner.isInSection(screenRecordEntry))
+ }
+
+ @Test
+ @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+ fun testDiscludeScreenRecordNotifInSection_flagDisabled() =
+ kosmos.runTest {
+ // GIVEN a screen record event + screen record notif that has a status bar chip
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "screenRecord", promoted = false) {
+ setImportance(NotificationManager.IMPORTANCE_DEFAULT)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(promotedNotificationsInteractor.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|screenRecord|0")
+ .inOrder()
+
+ // THEN the entry is NOT in the fgs section
+ assertFalse(sectioner.isInSection(screenRecordEntry))
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
fun promoterSelectsPromotedOngoing_flagEnabled() {
val promoter: NotifPromoter = withArgCaptor { verify(notifPipeline).addPromoter(capture()) }
@@ -234,8 +320,4 @@ class ColorizedFgsCoordinatorTest : SysuiTestCase() {
val person = Person.Builder().setName("person").build()
return Notification.CallStyle.forOngoingCall(person, pendingIntent)
}
-
- companion object {
- private const val NOTIF_USER_ID = 0
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index 4c099b305332..0ac944a43de6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -190,11 +190,22 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_basicTimeZero() {
+ assertExtractedTime(
+ hasTime = true,
+ hasChronometer = false,
+ provided = ProvidedTime.Value(0L),
+ expected = ExpectedTime.Time,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
fun extractTime_basicTimeNow() {
assertExtractedTime(
hasTime = true,
hasChronometer = false,
- whenOffset = Duration.ZERO,
+ provided = ProvidedTime.Offset(Duration.ZERO),
expected = ExpectedTime.Time,
)
}
@@ -205,7 +216,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
assertExtractedTime(
hasTime = true,
hasChronometer = false,
- whenOffset = (-5).minutes,
+ provided = ProvidedTime.Offset((-5).minutes),
expected = ExpectedTime.Time,
)
}
@@ -216,19 +227,31 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
assertExtractedTime(
hasTime = true,
hasChronometer = false,
- whenOffset = 5.minutes,
+ provided = ProvidedTime.Offset(5.minutes),
expected = ExpectedTime.Time,
)
}
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countUpZero() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = false,
+ provided = ProvidedTime.Value(0L),
+ expected = ExpectedTime.CountUp,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
fun extractTime_countUpNow() {
assertExtractedTime(
hasTime = false,
hasChronometer = true,
isCountDown = false,
- whenOffset = Duration.ZERO,
+ provided = ProvidedTime.Offset(Duration.ZERO),
expected = ExpectedTime.CountUp,
)
}
@@ -240,7 +263,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
hasTime = false,
hasChronometer = true,
isCountDown = false,
- whenOffset = (-5).minutes,
+ provided = ProvidedTime.Offset((-5).minutes),
expected = ExpectedTime.CountUp,
)
}
@@ -252,19 +275,31 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
hasTime = false,
hasChronometer = true,
isCountDown = false,
- whenOffset = 5.minutes,
+ provided = ProvidedTime.Offset(5.minutes),
expected = ExpectedTime.CountUp,
)
}
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+ fun extractTime_countDownZero() {
+ assertExtractedTime(
+ hasTime = false,
+ hasChronometer = true,
+ isCountDown = true,
+ provided = ProvidedTime.Value(0L),
+ expected = ExpectedTime.CountDown,
+ )
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
fun extractTime_countDownNow() {
assertExtractedTime(
hasTime = false,
hasChronometer = true,
isCountDown = true,
- whenOffset = Duration.ZERO,
+ provided = ProvidedTime.Offset(Duration.ZERO),
expected = ExpectedTime.CountDown,
)
}
@@ -276,7 +311,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
hasTime = false,
hasChronometer = true,
isCountDown = true,
- whenOffset = (-5).minutes,
+ provided = ProvidedTime.Offset((-5).minutes),
expected = ExpectedTime.CountDown,
)
}
@@ -288,7 +323,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
hasTime = false,
hasChronometer = true,
isCountDown = true,
- whenOffset = 5.minutes,
+ provided = ProvidedTime.Offset(5.minutes),
expected = ExpectedTime.CountDown,
)
}
@@ -299,6 +334,12 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
assertExtractedTime(hasTime = true, hasChronometer = true, expected = ExpectedTime.CountUp)
}
+ private sealed class ProvidedTime {
+ data class Value(val value: Long) : ProvidedTime()
+
+ data class Offset(val offset: Duration = Duration.ZERO) : ProvidedTime()
+ }
+
private enum class ExpectedTime {
Null,
Time,
@@ -310,7 +351,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
hasTime: Boolean = false,
hasChronometer: Boolean = false,
isCountDown: Boolean = false,
- whenOffset: Duration = Duration.ZERO,
+ provided: ProvidedTime = ProvidedTime.Offset(),
expected: ExpectedTime,
) {
// Set the two timebases to different (arbitrary) numbers, so we can verify whether the
@@ -318,14 +359,24 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
systemClock.setCurrentTimeMillis(1_739_570_992_579L)
systemClock.setElapsedRealtime(1_380_967_080L)
- val whenCurrentTime = systemClock.currentTimeMillis() + whenOffset.inWholeMilliseconds
- val whenElapsedRealtime = systemClock.elapsedRealtime() + whenOffset.inWholeMilliseconds
+ val providedCurrentTime =
+ when (provided) {
+ is ProvidedTime.Value -> provided.value
+ is ProvidedTime.Offset ->
+ systemClock.currentTimeMillis() + provided.offset.inWholeMilliseconds
+ }
+
+ val expectedCurrentTime =
+ when (providedCurrentTime) {
+ 0L -> systemClock.currentTimeMillis()
+ else -> providedCurrentTime
+ }
val entry = createEntry {
setShowWhen(hasTime)
setUsesChronometer(hasChronometer)
setChronometerCountDown(isCountDown)
- setWhen(whenCurrentTime)
+ setWhen(providedCurrentTime)
}
val content = extractContent(entry)
@@ -338,14 +389,18 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
ExpectedTime.Time -> {
val actual = content?.time as? When.Time
assertThat(actual).isNotNull()
- assertThat(actual?.currentTimeMillis).isEqualTo(whenCurrentTime)
+ assertThat(actual?.currentTimeMillis).isEqualTo(expectedCurrentTime)
}
ExpectedTime.CountDown,
ExpectedTime.CountUp -> {
+ val expectedElapsedRealtime =
+ expectedCurrentTime + systemClock.elapsedRealtime() -
+ systemClock.currentTimeMillis()
+
val actual = content?.time as? When.Chronometer
assertThat(actual).isNotNull()
- assertThat(actual?.elapsedRealtimeMillis).isEqualTo(whenElapsedRealtime)
+ assertThat(actual?.elapsedRealtimeMillis).isEqualTo(expectedElapsedRealtime)
assertThat(actual?.isCountDown).isEqualTo(expected == ExpectedTime.CountDown)
}
}
@@ -545,6 +600,11 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
if (promoted) {
notif.flags = FLAG_PROMOTED_ONGOING
}
+ // Notification uses System.currentTimeMillis() to initialize creationTime; overwrite that
+ // with the value from our mock clock.
+ if (notif.creationTime != 0L) {
+ notif.creationTime = systemClock.currentTimeMillis()
+ }
return NotificationEntryBuilder().setNotification(notif).build()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
index 6192399c522b..873ab5bc9c2c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.promoted.domain.interactor
+import android.app.Notification.FLAG_FOREGROUND_SERVICE
+import android.app.Notification.FLAG_ONGOING_EVENT
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -25,15 +27,26 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel
+import com.android.systemui.screenrecord.data.repository.screenRecordRepository
+import com.android.systemui.statusbar.chips.call.ui.viewmodel.CallChipViewModelTest.Companion.createStatusBarIconViewOrNull
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.notification.collection.buildNotificationEntry
import com.android.systemui.statusbar.notification.collection.buildOngoingCallEntry
import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry
+import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.addNotif
import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -76,6 +89,7 @@ class PromotedNotificationsInteractorTest : SysuiTestCase() {
// THEN the order of the notification keys should be the call then the RON
assertThat(orderedChipNotificationKeys)
.containsExactly("0|test_pkg|0|call|0", "0|test_pkg|0|ron|0")
+ .inOrder()
}
@Test
@@ -96,6 +110,521 @@ class PromotedNotificationsInteractorTest : SysuiTestCase() {
// THEN the order of the notification keys should be the call then the RON
assertThat(orderedChipNotificationKeys)
.containsExactly("0|test_pkg|0|call|0", "0|test_pkg|0|ron|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_noScreenRecordNotif_isEmpty() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ renderNotificationListInteractor.setRenderedList(emptyList())
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_nullHostPackageForScreenRecord_isEmpty() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ // hostPackage would be provided through mediaProjectionState
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.NotProjecting
+
+ val entry = buildNotificationEntry(tag = "record", promoted = false)
+ renderNotificationListInteractor.setRenderedList(listOf(entry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsPromotedScreenRecordNotif() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val screenRecordEntry = buildNotificationEntry(tag = "record", promoted = true)
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|record|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsNotPromotedScreenRecordNotif_ifOngoing() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "record", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|record|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsNotPromotedScreenRecordNotif_ifFgs() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "record", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|record|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_doesNotContainScreenRecordNotif_ifNotOngoingOrFgs() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val screenRecordEntry =
+ buildNotificationEntry(tag = "record", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(screenRecordEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsFgsScreenRecordNotif_whenNonFgsNotifExists() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val fgsEntry =
+ buildNotificationEntry(tag = "recordFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ val notFgsEntry =
+ buildNotificationEntry(tag = "recordNotFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(fgsEntry, notFgsEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|recordFgs|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsOngoingScreenRecordNotif_whenNonOngoingNotifExists() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val ongoingEntry =
+ buildNotificationEntry(tag = "recordOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ val notOngoingEntry =
+ buildNotificationEntry(tag = "recordNotOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(notOngoingEntry, ongoingEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|recordOngoing|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsFgsOngoingScreenRecordNotif_whenNonFgsOngoingNotifExists() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val ongoingAndFgsEntry =
+ buildNotificationEntry(tag = "recordBoth", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ val ongoingButNotFgsEntry =
+ buildNotificationEntry(tag = "recordOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ val fgsButNotOngoingEntry =
+ buildNotificationEntry(tag = "recordFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ }
+ renderNotificationListInteractor.setRenderedList(
+ listOf(fgsButNotOngoingEntry, ongoingButNotFgsEntry, ongoingAndFgsEntry)
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|recordBoth|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_twoEquivalentNotifsForScreenRecord_isEmpty() =
+ kosmos.runTest {
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(hostPackage = "test_pkg")
+
+ val entry1 =
+ buildNotificationEntry(tag = "entry1", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ val entry2 =
+ buildNotificationEntry(tag = "entry2", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(entry1, entry2))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_noMediProjNotif_isEmpty() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ renderNotificationListInteractor.setRenderedList(emptyList())
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsPromotedMediaProjNotif() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val mediaProjEntry = buildNotificationEntry(tag = "proj", promoted = true)
+ renderNotificationListInteractor.setRenderedList(listOf(mediaProjEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).containsExactly("0|test_pkg|0|proj|0").inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsNotPromotedMediaProjNotif_ifOngoing() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val mediaProjEntry =
+ buildNotificationEntry(tag = "proj", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(mediaProjEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).containsExactly("0|test_pkg|0|proj|0").inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsNotPromotedMediaProjNotif_ifFgs() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val mediaProjEntry =
+ buildNotificationEntry(tag = "proj", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(mediaProjEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).containsExactly("0|test_pkg|0|proj|0").inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_doesNotContainMediaProjNotif_ifNotOngoingOrFgs() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val mediaProjEntry =
+ buildNotificationEntry(tag = "proj", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(mediaProjEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsFgsMediaProjNotif_whenNonFgsNotifExists() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val fgsEntry =
+ buildNotificationEntry(tag = "projFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ val notFgsEntry =
+ buildNotificationEntry(tag = "projNotFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(fgsEntry, notFgsEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|projFgs|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsOngoingMediaProjNotif_whenNonOngoingNotifExists() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val ongoingEntry =
+ buildNotificationEntry(tag = "projOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ val notOngoingEntry =
+ buildNotificationEntry(tag = "projNotOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(notOngoingEntry, ongoingEntry))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|projOngoing|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_containsFgsOngoingMediaProjNotif_whenNonFgsOngoingNotifExists() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val ongoingAndFgsEntry =
+ buildNotificationEntry(tag = "projBoth", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ }
+ val ongoingButNotFgsEntry =
+ buildNotificationEntry(tag = "projOngoing", promoted = false) {
+ setFlag(context, FLAG_ONGOING_EVENT, true)
+ setFlag(context, FLAG_FOREGROUND_SERVICE, false)
+ }
+ val fgsButNotOngoingEntry =
+ buildNotificationEntry(tag = "projFgs", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ setFlag(context, FLAG_ONGOING_EVENT, false)
+ }
+ renderNotificationListInteractor.setRenderedList(
+ listOf(fgsButNotOngoingEntry, ongoingButNotFgsEntry, ongoingAndFgsEntry)
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("0|test_pkg|0|projBoth|0")
+ .inOrder()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_twoEquivalentNotifsForMediaProj_isEmpty() =
+ kosmos.runTest {
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "test_pkg",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+
+ val entry1 =
+ buildNotificationEntry(tag = "entry1", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ val entry2 =
+ buildNotificationEntry(tag = "entry2", promoted = false) {
+ setFlag(context, FLAG_FOREGROUND_SERVICE, true)
+ }
+ renderNotificationListInteractor.setRenderedList(listOf(entry1, entry2))
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).isEmpty()
+ }
+
+ @Test
+ fun orderedChipNotificationKeys_maintainsPromotedNotifOrder() =
+ kosmos.runTest {
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif1",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif1").build(),
+ )
+ )
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif2",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif2").build(),
+ )
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys).containsExactly("notif1", "notif2").inOrder()
+ }
+
+ // The ranking between different chips should stay consistent between
+ // PromotedNotificationsInteractor and OngoingActivityChipsViewModel.
+ // See OngoingActivityChipsWithNotifsViewModelTest#chips_screenRecordAndCallAndPromotedNotifs
+ // test for the right ranking.
+ @Test
+ fun orderedChipNotificationKeys_rankingIsCorrect() =
+ kosmos.runTest {
+ // Screen record
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+ fakeMediaProjectionRepository.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ hostPackage = "screen.record.package",
+ hostDeviceName = null,
+ createTask(taskId = 1),
+ )
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "screenRecordKey",
+ packageName = "screen.record.package",
+ isOngoingEvent = true,
+ )
+ )
+ // Call
+ addOngoingCallState(key = "callKey")
+ // Other promoted notifs
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif1",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif1").build(),
+ )
+ )
+ activeNotificationListRepository.addNotif(
+ activeNotificationModel(
+ key = "notif2",
+ statusBarChipIcon = createStatusBarIconViewOrNull(),
+ promotedContent = PromotedNotificationContentModel.Builder("notif2").build(),
+ )
+ )
+
+ val orderedChipNotificationKeys by
+ collectLastValue(underTest.orderedChipNotificationKeys)
+
+ assertThat(orderedChipNotificationKeys)
+ .containsExactly("screenRecordKey", "callKey", "notif1", "notif2")
+ .inOrder()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
index 0ac5fe95957c..16663def16a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
@@ -67,8 +67,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.promoted.domain.interactor.PackageDemotionInteractor
import com.android.systemui.statusbar.notification.row.icon.AppIconProvider
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
-import com.android.systemui.statusbar.notification.row.icon.appIconProvider
-import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider
+import com.android.systemui.statusbar.notification.row.icon.mockAppIconProvider
+import com.android.systemui.statusbar.notification.row.icon.mockNotificationIconStyleProvider
import com.android.systemui.testKosmos
import com.android.telecom.telecomManager
import com.google.common.truth.Truth.assertThat
@@ -80,6 +80,7 @@ import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -101,6 +102,8 @@ class NotificationInfoTest : SysuiTestCase() {
private lateinit var entry: NotificationEntry
private val mockPackageManager = kosmos.mockPackageManager
+ private val mockAppIconProvider = kosmos.mockAppIconProvider
+ private val mockIconStyleProvider = kosmos.mockNotificationIconStyleProvider
private val uiEventLogger = kosmos.uiEventLoggerFake
private val testableLooper by lazy { kosmos.testableLooper }
@@ -202,7 +205,8 @@ class NotificationInfoTest : SysuiTestCase() {
}
@Test
- fun testBindNotification_SetsPackageIcon() {
+ @DisableFlags(com.android.systemui.Flags.FLAG_NOTIFICATIONS_REDESIGN_GUTS)
+ fun testBindNotification_SetsPackageIcon_flagOff() {
val iconDrawable = mock<Drawable>()
whenever(mockPackageManager.getApplicationIcon(any<ApplicationInfo>()))
.thenReturn(iconDrawable)
@@ -212,6 +216,26 @@ class NotificationInfoTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_NOTIFICATIONS_REDESIGN_GUTS)
+ fun testBindNotification_SetsPackageIcon_flagOn() {
+ val iconDrawable = mock<Drawable>()
+ whenever(mockIconStyleProvider.shouldShowWorkProfileBadge(anyOrNull(), anyOrNull()))
+ .thenReturn(false)
+ whenever(
+ mockAppIconProvider.getOrFetchAppIcon(
+ anyOrNull(),
+ anyOrNull(),
+ anyBoolean(),
+ anyBoolean(),
+ )
+ )
+ .thenReturn(iconDrawable)
+ bindNotification()
+ val iconView = underTest.findViewById<ImageView>(R.id.pkg_icon)
+ assertThat(iconView.drawable).isEqualTo(iconDrawable)
+ }
+
+ @Test
fun testBindNotification_noDelegate() {
bindNotification()
val nameView = underTest.findViewById<TextView>(R.id.delegate_name)
@@ -894,8 +918,8 @@ class NotificationInfoTest : SysuiTestCase() {
private fun bindNotification(
pm: PackageManager = this.mockPackageManager,
iNotificationManager: INotificationManager = this.mockINotificationManager,
- appIconProvider: AppIconProvider = kosmos.appIconProvider,
- iconStyleProvider: NotificationIconStyleProvider = kosmos.notificationIconStyleProvider,
+ appIconProvider: AppIconProvider = this.mockAppIconProvider,
+ iconStyleProvider: NotificationIconStyleProvider = this.mockIconStyleProvider,
onUserInteractionCallback: OnUserInteractionCallback = this.onUserInteractionCallback,
channelEditorDialogController: ChannelEditorDialogController =
this.channelEditorDialogController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index ce120c51db6a..95366568a37a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.platform.test.annotations.DisableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -38,6 +39,7 @@ import android.view.ViewGroup;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.systemui.Flags;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.collection.EntryAdapter;
@@ -418,6 +420,7 @@ public class NotificationMenuRowTest extends LeakCheckedTest {
assertTrue("when alpha is .5, menu is visible", row.isMenuVisible());
}
+ @DisableFlags(Flags.FLAG_MAGNETIC_NOTIFICATION_SWIPES)
@Test
public void testOnTouchMove() {
NotificationMenuRow row = Mockito.spy(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
index ccc8be7de038..f52f96efb9d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
@@ -130,14 +130,16 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
kosmos.testScope.runTest {
// GIVEN a threshold of 100 px
val threshold = 100f
- underTest.setSwipeThresholdPx(threshold)
+ underTest.onDensityChange(
+ threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ )
// GIVEN that targets are set and the rows are being pulled
setTargets()
underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
// WHEN setting a translation that will fall below the threshold
- val translation = threshold / underTest.swipedRowMultiplier - 50f
+ val translation = 50f
underTest.setMagneticRowTranslation(swipedRow, translation)
// THEN the targets continue to be pulled and translations are set
@@ -150,7 +152,9 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
kosmos.testScope.runTest {
// GIVEN a threshold of 100 px
val threshold = 100f
- underTest.setSwipeThresholdPx(threshold)
+ underTest.onDensityChange(
+ threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ )
// GIVEN that targets are set and the rows are being pulled
canRowBeDismissed = false
@@ -158,7 +162,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
// WHEN setting a translation that will fall below the threshold
- val translation = threshold / underTest.swipedRowMultiplier - 50f
+ val translation = 50f
underTest.setMagneticRowTranslation(swipedRow, translation)
// THEN the targets continue to be pulled and reduced translations are set
@@ -172,14 +176,16 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
kosmos.testScope.runTest {
// GIVEN a threshold of 100 px
val threshold = 100f
- underTest.setSwipeThresholdPx(threshold)
+ underTest.onDensityChange(
+ threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ )
// GIVEN that targets are set and the rows are being pulled
setTargets()
underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
// WHEN setting a translation that will fall above the threshold
- val translation = threshold / underTest.swipedRowMultiplier + 50f
+ val translation = 150f
underTest.setMagneticRowTranslation(swipedRow, translation)
// THEN the swiped view detaches and the correct detach haptics play
@@ -192,7 +198,9 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
kosmos.testScope.runTest {
// GIVEN a threshold of 100 px
val threshold = 100f
- underTest.setSwipeThresholdPx(threshold)
+ underTest.onDensityChange(
+ threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ )
// GIVEN that targets are set and the rows are being pulled
canRowBeDismissed = false
@@ -200,7 +208,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
// WHEN setting a translation that will fall above the threshold
- val translation = threshold / underTest.swipedRowMultiplier + 50f
+ val translation = 150f
underTest.setMagneticRowTranslation(swipedRow, translation)
// THEN the swiped view does not detach and the reduced translation is set
@@ -240,6 +248,19 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
}
@Test
+ fun onMagneticInteractionEnd_whileTargetsSet_goesToIdle() =
+ kosmos.testScope.runTest {
+ // GIVEN that targets are set
+ setTargets()
+
+ // WHEN the interaction ends on the row
+ underTest.onMagneticInteractionEnd(swipedRow, velocity = null)
+
+ // THEN the state resets
+ assertThat(underTest.currentState).isEqualTo(State.IDLE)
+ }
+
+ @Test
fun onMagneticInteractionEnd_whileDetached_goesToIdle() =
kosmos.testScope.runTest {
// GIVEN the swiped row is detached
@@ -294,6 +315,29 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
assertThat(underTest.isSwipedViewRoundableSet).isFalse()
}
+ @Test
+ fun isMagneticRowDismissible_isDismissibleWhenDetached() =
+ kosmos.testScope.runTest {
+ setDetachedState()
+
+ val isDismissible = underTest.isMagneticRowSwipeDetached(swipedRow)
+ assertThat(isDismissible).isTrue()
+ }
+
+ @Test
+ fun setMagneticRowTranslation_whenDetached_belowAttachThreshold_reattaches() =
+ kosmos.testScope.runTest {
+ // GIVEN that the swiped view has been detached
+ setDetachedState()
+
+ // WHEN setting a new translation above the attach threshold
+ val translation = 50f
+ underTest.setMagneticRowTranslation(swipedRow, translation)
+
+ // THEN the swiped view reattaches magnetically and the state becomes PULLING
+ assertThat(underTest.currentState).isEqualTo(State.PULLING)
+ }
+
@After
fun tearDown() {
// We reset the manager so that all MagneticRowListener can cancel all animations
@@ -302,14 +346,16 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
private fun setDetachedState() {
val threshold = 100f
- underTest.setSwipeThresholdPx(threshold)
+ underTest.onDensityChange(
+ threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ )
// Set the pulling state
setTargets()
underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
// Set a translation that will fall above the threshold
- val translation = threshold / underTest.swipedRowMultiplier + 50f
+ val translation = 150f
underTest.setMagneticRowTranslation(swipedRow, translation)
assertThat(underTest.currentState).isEqualTo(State.DETACHED)
@@ -327,8 +373,8 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() {
private fun MagneticRowListener.asTestableListener(rowIndex: Int): MagneticRowListener {
val delegate = this
return object : MagneticRowListener {
- override fun setMagneticTranslation(translation: Float) {
- delegate.setMagneticTranslation(translation)
+ override fun setMagneticTranslation(translation: Float, trackEagerly: Boolean) {
+ delegate.setMagneticTranslation(translation, trackEagerly)
}
override fun triggerMagneticForce(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 789701f5e4b0..de48f4018989 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -49,6 +49,7 @@ import android.view.ViewConfiguration;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.flags.FakeFeatureFlags;
@@ -362,6 +363,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
verify(mSwipeHelper, times(1)).isFalseGesture();
}
+ @DisableFlags(Flags.FLAG_MAGNETIC_NOTIFICATION_SWIPES)
@Test
public void testIsDismissGesture_farEnough() {
doReturn(false).when(mSwipeHelper).isFalseGesture();
@@ -374,6 +376,20 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
verify(mSwipeHelper, times(1)).isFalseGesture();
}
+ @EnableFlags(Flags.FLAG_MAGNETIC_NOTIFICATION_SWIPES)
+ @Test
+ public void testIsDismissGesture_magneticSwipeIsDismissible() {
+ doReturn(false).when(mSwipeHelper).isFalseGesture();
+ doReturn(false).when(mSwipeHelper).swipedFarEnough();
+ doReturn(false).when(mSwipeHelper).swipedFastEnough();
+ doReturn(true).when(mCallback).isMagneticViewDetached(any());
+ when(mCallback.canChildBeDismissedInDirection(any(), anyBoolean())).thenReturn(true);
+ when(mEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_UP);
+
+ assertTrue("Should be a dismissal", mSwipeHelper.isDismissGesture(mEvent));
+ verify(mSwipeHelper, times(1)).isFalseGesture();
+ }
+
@Test
public void testIsDismissGesture_notFarOrFastEnough() {
doReturn(false).when(mSwipeHelper).isFalseGesture();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
index 57e63a595b8f..9042ac45cd4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -19,110 +19,69 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.log.table.logcatTableLogBuffer
import com.android.systemui.statusbar.connectivity.MobileIconCarrierIdOverridesFake
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
-import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.fake
import com.android.systemui.testKosmos
-import com.android.systemui.util.CarrierConfigTracker
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class LocationBasedMobileIconViewModelKairosTest : SysuiTestCase() {
- private val kosmos = testKosmos()
-
- private lateinit var commonImpl: MobileIconViewModelCommonKairos
- private lateinit var homeIcon: HomeMobileIconViewModelKairos
- private lateinit var qsIcon: QsMobileIconViewModelKairos
- private lateinit var keyguardIcon: KeyguardMobileIconViewModelKairos
- private lateinit var iconsInteractor: MobileIconsInteractor
- private lateinit var interactor: MobileIconInteractor
- private val connectionsRepository = kosmos.fakeMobileConnectionsRepository
- private lateinit var repository: FakeMobileConnectionRepository
- private lateinit var airplaneModeInteractor: AirplaneModeInteractor
-
- private val connectivityRepository = FakeConnectivityRepository()
- private val flags =
- FakeFeatureFlagsClassic().also {
- it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
- }
- @Mock private lateinit var constants: ConnectivityConstants
- private val tableLogBuffer =
- logcatTableLogBuffer(kosmos, "LocationBasedMobileIconViewModelTest")
- @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
-
- private val testDispatcher = UnconfinedTestDispatcher()
- private val testScope = TestScope(testDispatcher)
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- airplaneModeInteractor =
- AirplaneModeInteractor(
- FakeAirplaneModeRepository(),
- FakeConnectivityRepository(),
- connectionsRepository,
- )
- repository =
- FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer).apply {
- isInService.value = true
- cdmaLevel.value = 1
- primaryLevel.value = 1
- isEmergencyOnly.value = false
- numberOfLevels.value = 4
- resolvedNetworkType.value = ResolvedNetworkType.DefaultNetworkType(lookupKey = "3G")
- dataConnectionState.value = DataConnectionState.Connected
- }
+ private val Kosmos.commonImpl: MobileIconViewModelKairosCommon by ActivatedKairosFixture {
+ MobileIconViewModelKairos(
+ SUB_1_ID,
+ interactor,
+ airplaneModeInteractor,
+ constants,
+ featureFlagsClassic,
+ )
+ }
- connectionsRepository.activeMobileDataRepository.value = repository
+ private val Kosmos.homeIcon: HomeMobileIconViewModelKairos by
+ Kosmos.Fixture { HomeMobileIconViewModelKairos(commonImpl, mock()) }
- connectivityRepository.apply { setMobileConnected() }
+ private val Kosmos.qsIcon: QsMobileIconViewModelKairos by
+ Kosmos.Fixture { QsMobileIconViewModelKairos(commonImpl) }
- iconsInteractor =
- MobileIconsInteractorImpl(
- connectionsRepository,
- carrierConfigTracker,
- tableLogBuffer,
- connectivityRepository,
- FakeUserSetupRepository(),
- testScope.backgroundScope,
- context,
- flags,
- )
+ private val Kosmos.keyguardIcon: KeyguardMobileIconViewModelKairos by
+ Kosmos.Fixture { KeyguardMobileIconViewModelKairos(commonImpl) }
+
+ private val Kosmos.iconsInteractor: MobileIconsInteractorKairos
+ get() = mobileIconsInteractorKairos
- interactor =
- MobileIconInteractorImpl(
- testScope.backgroundScope,
+ private val Kosmos.interactor: MobileIconInteractorKairos by
+ Kosmos.Fixture {
+ MobileIconInteractorKairosImpl(
iconsInteractor.activeDataConnectionHasDataEnabled,
iconsInteractor.alwaysShowDataRatIcon,
iconsInteractor.alwaysUseCdmaLevel,
@@ -136,50 +95,74 @@ class LocationBasedMobileIconViewModelKairosTest : SysuiTestCase() {
context,
MobileIconCarrierIdOverridesFake(),
)
+ }
- commonImpl =
- MobileIconViewModelKairos(
- SUB_1_ID,
- interactor,
- airplaneModeInteractor,
- constants,
- testScope.backgroundScope,
- )
-
- homeIcon = HomeMobileIconViewModelKairos(commonImpl, mock())
- qsIcon = QsMobileIconViewModelKairos(commonImpl)
- keyguardIcon = KeyguardMobileIconViewModelKairos(commonImpl)
- }
+ private val Kosmos.repository: FakeMobileConnectionRepositoryKairos by
+ Kosmos.Fixture {
+ FakeMobileConnectionRepositoryKairos(SUB_1_ID, kairos, tableLogBuffer).apply {
+ isInService.setValue(true)
+ cdmaLevel.setValue(1)
+ primaryLevel.setValue(1)
+ isEmergencyOnly.setValue(false)
+ numberOfLevels.setValue(4)
+ resolvedNetworkType.setValue(
+ ResolvedNetworkType.DefaultNetworkType(lookupKey = "3G")
+ )
+ dataConnectionState.setValue(DataConnectionState.Connected)
+ }
+ }
- @Test
- fun locationBasedViewModelsReceiveSameIconIdWhenCommonImplUpdates() =
- testScope.runTest {
- var latestHome: SignalIconModel? = null
- val homeJob = homeIcon.icon.onEach { latestHome = it }.launchIn(this)
+ private val Kosmos.constants: ConnectivityConstants by Kosmos.Fixture { mock() }
+ private val Kosmos.tableLogBuffer by
+ Kosmos.Fixture { logcatTableLogBuffer(this, "LocationBasedMobileIconViewModelTest") }
+
+ private val kosmos =
+ testKosmos().apply {
+ useUnconfinedTestDispatcher()
+ mobileConnectionsRepositoryKairos =
+ fakeMobileConnectionsRepositoryKairos.apply {
+ setActiveMobileDataSubscriptionId(SUB_1_ID)
+ subscriptions.setValue(
+ listOf(
+ SubscriptionModel(
+ SUB_1_ID,
+ carrierName = "carrierName",
+ profileClass = 0,
+ )
+ )
+ )
+ }
+ connectivityRepository.fake.apply { setMobileConnected() }
+ featureFlagsClassic.fake.apply {
+ set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
+ }
+ }
- var latestQs: SignalIconModel? = null
- val qsJob = qsIcon.icon.onEach { latestQs = it }.launchIn(this)
+ private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+ kosmos.run { runKairosTest { block() } }
- var latestKeyguard: SignalIconModel? = null
- val keyguardJob = keyguardIcon.icon.onEach { latestKeyguard = it }.launchIn(this)
+ @Test
+ fun locationBasedViewModelsReceiveSameIconIdWhenCommonImplUpdates() = runTest {
+ repository.dataEnabled.setValue(true)
+ repository.isInService.setValue(true)
- var expected = defaultSignal(level = 1)
+ val latestHome by homeIcon.icon.collectLastValue()
+ val latestQs by qsIcon.icon.collectLastValue()
+ val latestKeyguard by keyguardIcon.icon.collectLastValue()
- assertThat(latestHome).isEqualTo(expected)
- assertThat(latestQs).isEqualTo(expected)
- assertThat(latestKeyguard).isEqualTo(expected)
+ var expected = defaultSignal(level = 1)
- repository.setAllLevels(2)
- expected = defaultSignal(level = 2)
+ assertThat(latestHome).isEqualTo(expected)
+ assertThat(latestQs).isEqualTo(expected)
+ assertThat(latestKeyguard).isEqualTo(expected)
- assertThat(latestHome).isEqualTo(expected)
- assertThat(latestQs).isEqualTo(expected)
- assertThat(latestKeyguard).isEqualTo(expected)
+ repository.setAllLevels(2)
+ expected = defaultSignal(level = 2)
- homeJob.cancel()
- qsJob.cancel()
- keyguardJob.cancel()
- }
+ assertThat(latestHome).isEqualTo(expected)
+ assertThat(latestQs).isEqualTo(expected)
+ assertThat(latestKeyguard).isEqualTo(expected)
+ }
companion object {
private const val SUB_1_ID = 1
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
index 6b114a8256f2..68499d1bc57c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -28,1039 +28,893 @@ import com.android.systemui.Flags.FLAG_STATUS_BAR_STATIC_INOUT_INDICATORS
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.log.table.logcatTableLogBuffer
import com.android.systemui.res.R
import com.android.systemui.statusbar.connectivity.MobileIconCarrierIdOverridesFake
import com.android.systemui.statusbar.core.NewStatusBarIcons
import com.android.systemui.statusbar.core.StatusBarRootModernization
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.fake
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository.Companion.DEFAULT_NETWORK_NAME
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
-import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.fake
import com.android.systemui.testKosmos
-import com.android.systemui.util.CarrierConfigTracker
-import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.filterIsInstance
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class MobileIconViewModelKairosTest : SysuiTestCase() {
- private val kosmos = testKosmos()
-
- private var connectivityRepository = FakeConnectivityRepository()
-
- private lateinit var underTest: MobileIconViewModelKairos
- private lateinit var interactor: MobileIconInteractorImpl
- private lateinit var iconsInteractor: MobileIconsInteractorImpl
- private lateinit var repository: FakeMobileConnectionRepository
- private lateinit var connectionsRepository: FakeMobileConnectionsRepository
- private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
- private lateinit var airplaneModeInteractor: AirplaneModeInteractor
- @Mock private lateinit var constants: ConnectivityConstants
- private val tableLogBuffer = logcatTableLogBuffer(kosmos, "MobileIconViewModelTest")
- @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
-
- private val flags =
- FakeFeatureFlagsClassic().also {
- it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
+
+ private val Kosmos.underTest: MobileIconViewModelKairos by ActivatedKairosFixture {
+ MobileIconViewModelKairos(
+ SUB_1_ID,
+ interactor,
+ airplaneModeInteractor,
+ constants,
+ featureFlagsClassic,
+ )
+ }
+ private val Kosmos.interactor: MobileIconInteractorKairos by ActivatedKairosFixture {
+ MobileIconInteractorKairosImpl(
+ mobileIconsInteractorKairos.activeDataConnectionHasDataEnabled,
+ mobileIconsInteractorKairos.alwaysShowDataRatIcon,
+ mobileIconsInteractorKairos.alwaysUseCdmaLevel,
+ mobileIconsInteractorKairos.isSingleCarrier,
+ mobileIconsInteractorKairos.mobileIsDefault,
+ mobileIconsInteractorKairos.defaultMobileIconMapping,
+ mobileIconsInteractorKairos.defaultMobileIconGroup,
+ mobileIconsInteractorKairos.isDefaultConnectionFailed,
+ mobileIconsInteractorKairos.isForceHidden,
+ repository,
+ context,
+ MobileIconCarrierIdOverridesFake(),
+ )
+ }
+ private val Kosmos.repository: FakeMobileConnectionRepositoryKairos by
+ Kosmos.Fixture {
+ FakeMobileConnectionRepositoryKairos(SUB_1_ID, kairos, tableLogBuffer)
+ .also {
+ mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(
+ SUB_1_ID
+ )
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(
+ listOf(
+ SubscriptionModel(
+ SUB_1_ID,
+ carrierName = "carrierName",
+ profileClass = 0,
+ )
+ )
+ )
+ }
+ .apply {
+ isInService.setValue(true)
+ dataConnectionState.setValue(DataConnectionState.Connected)
+ dataEnabled.setValue(true)
+ setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ }
}
- private val testDispatcher = UnconfinedTestDispatcher()
- private val testScope = TestScope(testDispatcher)
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- whenever(constants.hasDataCapabilities).thenReturn(true)
-
- connectionsRepository =
- FakeMobileConnectionsRepository(FakeMobileMappingsProxy(), tableLogBuffer)
-
- repository =
- FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer).apply {
- setNetworkTypeKey(connectionsRepository.GSM_KEY)
- isInService.value = true
- dataConnectionState.value = DataConnectionState.Connected
- dataEnabled.value = true
+ private val Kosmos.constants: ConnectivityConstants by
+ Kosmos.Fixture { mock { on { hasDataCapabilities } doReturn true } }
+ private val Kosmos.tableLogBuffer by
+ Kosmos.Fixture { logcatTableLogBuffer(this, "MobileIconViewModelKairosTest") }
+
+ private val kosmos =
+ testKosmos().apply {
+ useUnconfinedTestDispatcher()
+ mobileConnectionsRepositoryKairos =
+ fakeMobileConnectionsRepositoryKairos.apply { mobileIsDefault.setValue(true) }
+ featureFlagsClassic.fake.apply {
+ set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
}
- connectionsRepository.activeMobileDataRepository.value = repository
- connectionsRepository.mobileIsDefault.value = true
-
- airplaneModeRepository = FakeAirplaneModeRepository()
- airplaneModeInteractor =
- AirplaneModeInteractor(
- airplaneModeRepository,
- connectivityRepository,
- kosmos.fakeMobileConnectionsRepository,
- )
-
- iconsInteractor =
- MobileIconsInteractorImpl(
- connectionsRepository,
- carrierConfigTracker,
- tableLogBuffer,
- connectivityRepository,
- FakeUserSetupRepository(),
- testScope.backgroundScope,
- context,
- flags,
- )
+ }
- interactor =
- MobileIconInteractorImpl(
- testScope.backgroundScope,
- iconsInteractor.activeDataConnectionHasDataEnabled,
- iconsInteractor.alwaysShowDataRatIcon,
- iconsInteractor.alwaysUseCdmaLevel,
- iconsInteractor.isSingleCarrier,
- iconsInteractor.mobileIsDefault,
- iconsInteractor.defaultMobileIconMapping,
- iconsInteractor.defaultMobileIconGroup,
- iconsInteractor.isDefaultConnectionFailed,
- iconsInteractor.isForceHidden,
- repository,
- context,
- MobileIconCarrierIdOverridesFake(),
- )
- createAndSetViewModel()
- }
+ private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+ kosmos.run { runKairosTest { block() } }
@Test
- fun isVisible_notDataCapable_alwaysFalse() =
- testScope.runTest {
- // Create a new view model here so the constants are properly read
- whenever(constants.hasDataCapabilities).thenReturn(false)
- createAndSetViewModel()
-
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+ fun isVisible_notDataCapable_alwaysFalse() = runTest {
+ // Create a new view model here so the constants are properly read
+ constants.stub { on { hasDataCapabilities } doReturn false }
- assertThat(latest).isFalse()
+ val latest by underTest.isVisible.collectLastValue()
- job.cancel()
- }
+ assertThat(latest).isFalse()
+ }
@Test
- fun isVisible_notAirplane_notForceHidden_true() =
- testScope.runTest {
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+ fun isVisible_notAirplane_notForceHidden_true() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- airplaneModeRepository.setIsAirplaneMode(false)
+ airplaneModeRepository.fake.setIsAirplaneMode(false)
- assertThat(latest).isTrue()
-
- job.cancel()
- }
+ assertThat(latest).isTrue()
+ }
@Test
- fun isVisible_airplaneAndNotAllowed_false() =
- testScope.runTest {
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
-
- airplaneModeRepository.setIsAirplaneMode(true)
- repository.isAllowedDuringAirplaneMode.value = false
- connectivityRepository.setForceHiddenIcons(setOf())
+ fun isVisible_airplaneAndNotAllowed_false() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- assertThat(latest).isFalse()
+ airplaneModeRepository.fake.setIsAirplaneMode(true)
+ repository.isAllowedDuringAirplaneMode.setValue(false)
+ connectivityRepository.fake.setForceHiddenIcons(setOf())
- job.cancel()
- }
+ assertThat(latest).isEqualTo(false)
+ }
/** Regression test for b/291993542. */
@Test
- fun isVisible_airplaneButAllowed_true() =
- testScope.runTest {
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
-
- airplaneModeRepository.setIsAirplaneMode(true)
- repository.isAllowedDuringAirplaneMode.value = true
- connectivityRepository.setForceHiddenIcons(setOf())
+ fun isVisible_airplaneButAllowed_true() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- assertThat(latest).isTrue()
+ airplaneModeRepository.fake.setIsAirplaneMode(true)
+ repository.isAllowedDuringAirplaneMode.setValue(true)
+ connectivityRepository.fake.setForceHiddenIcons(setOf())
- job.cancel()
- }
+ assertThat(latest).isTrue()
+ }
@Test
- fun isVisible_forceHidden_false() =
- testScope.runTest {
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+ fun isVisible_forceHidden_false() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- airplaneModeRepository.setIsAirplaneMode(false)
- connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
+ airplaneModeRepository.fake.setIsAirplaneMode(false)
+ connectivityRepository.fake.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
- assertThat(latest).isFalse()
-
- job.cancel()
- }
+ assertThat(latest).isFalse()
+ }
@Test
- fun isVisible_respondsToUpdates() =
- testScope.runTest {
- var latest: Boolean? = null
- val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
-
- airplaneModeRepository.setIsAirplaneMode(false)
- connectivityRepository.setForceHiddenIcons(setOf())
+ fun isVisible_respondsToUpdates() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- assertThat(latest).isTrue()
+ airplaneModeRepository.fake.setIsAirplaneMode(false)
+ connectivityRepository.fake.setForceHiddenIcons(setOf())
- airplaneModeRepository.setIsAirplaneMode(true)
- assertThat(latest).isFalse()
+ assertThat(latest).isEqualTo(true)
- repository.isAllowedDuringAirplaneMode.value = true
- assertThat(latest).isTrue()
+ airplaneModeRepository.fake.setIsAirplaneMode(true)
+ assertThat(latest).isEqualTo(false)
- connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
- assertThat(latest).isFalse()
+ repository.isAllowedDuringAirplaneMode.setValue(true)
+ assertThat(latest).isEqualTo(true)
- job.cancel()
- }
+ connectivityRepository.fake.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
+ assertThat(latest).isEqualTo(false)
+ }
@Test
- fun isVisible_satellite_respectsAirplaneMode() =
- testScope.runTest {
- val latest by collectLastValue(underTest.isVisible)
+ fun isVisible_satellite_respectsAirplaneMode() = runTest {
+ val latest by underTest.isVisible.collectLastValue()
- repository.isNonTerrestrial.value = true
- airplaneModeInteractor.setIsAirplaneMode(false)
+ repository.isNonTerrestrial.setValue(true)
+ airplaneModeInteractor.setIsAirplaneMode(false)
- assertThat(latest).isTrue()
+ assertThat(latest).isTrue()
- airplaneModeInteractor.setIsAirplaneMode(true)
+ airplaneModeInteractor.setIsAirplaneMode(true)
- assertThat(latest).isFalse()
- }
+ assertThat(latest).isFalse()
+ }
@Test
- fun contentDescription_notInService_usesNoPhone() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_notInService_usesNoPhone() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.isInService.value = false
+ repository.isInService.setValue(false)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- }
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
@Test
- fun contentDescription_includesNetworkName() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_includesNetworkName() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.isInService.value = true
- repository.networkName.value = NetworkNameModel.SubscriptionDerived("Test Network Name")
- repository.numberOfLevels.value = 5
- repository.setAllLevels(3)
+ repository.isInService.setValue(true)
+ repository.networkName.setValue(NetworkNameModel.SubscriptionDerived("Test Network Name"))
+ repository.numberOfLevels.setValue(5)
+ repository.setAllLevels(3)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
- }
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
+ }
@Test
- fun contentDescription_inService_usesLevel() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_inService_usesLevel() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.setAllLevels(2)
+ repository.setAllLevels(2)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
- repository.setAllLevels(0)
+ repository.setAllLevels(0)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- }
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
@Test
- fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.inflateSignalStrength.value = false
- repository.setAllLevels(-1)
+ repository.inflateSignalStrength.setValue(false)
+ repository.setAllLevels(-1)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- repository.setAllLevels(100)
+ repository.setAllLevels(100)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- }
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
@Test
- fun contentDescription_nonInflated_levelStrings() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_nonInflated_levelStrings() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.inflateSignalStrength.value = false
- repository.setAllLevels(0)
+ repository.inflateSignalStrength.setValue(false)
+ repository.setAllLevels(0)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- repository.setAllLevels(1)
+ repository.setAllLevels(1)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
- repository.setAllLevels(2)
+ repository.setAllLevels(2)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
- repository.setAllLevels(3)
+ repository.setAllLevels(3)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
- repository.setAllLevels(4)
+ repository.setAllLevels(4)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
- }
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
+ }
@Test
- fun contentDescription_inflated_invalidLevelUsesNoSignalText() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_inflated_invalidLevelUsesNoSignalText() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.inflateSignalStrength.value = true
- repository.numberOfLevels.value = 6
+ repository.inflateSignalStrength.setValue(true)
+ repository.numberOfLevels.setValue(6)
+ repository.setAllLevels(-2)
- repository.setAllLevels(-2)
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ repository.setAllLevels(100)
- repository.setAllLevels(100)
-
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
- }
+ assertThat(latest as MobileContentDescription.Cellular)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+ }
@Test
- fun contentDescription_inflated_levelStrings() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
+ fun contentDescription_inflated_levelStrings() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
- repository.inflateSignalStrength.value = true
- repository.numberOfLevels.value = 6
+ repository.inflateSignalStrength.setValue(true)
+ repository.numberOfLevels.setValue(6)
- // Note that the _repo_ level is 1 lower than the reported level through the interactor
+ // Note that the _repo_ level is 1 lower than the reported level through the interactor
- repository.setAllLevels(0)
+ repository.setAllLevels(0)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
- repository.setAllLevels(1)
+ repository.setAllLevels(1)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
- repository.setAllLevels(2)
+ repository.setAllLevels(2)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
- repository.setAllLevels(3)
+ repository.setAllLevels(3)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
- repository.setAllLevels(4)
+ repository.setAllLevels(4)
- assertThat(latest as MobileContentDescription.Cellular)
- .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
- }
+ assertThat(latest)
+ .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
+ }
@Test
- fun contentDescription_nonInflated_testABunchOfLevelsForNull() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
-
- repository.inflateSignalStrength.value = false
- repository.numberOfLevels.value = 5
-
- // -1 and 5 are out of the bounds for non-inflated content descriptions
- for (i in -1..5) {
- repository.setAllLevels(i)
- when (i) {
- -1,
- 5 ->
- assertWithMessage("Level $i is expected to be 'no signal'")
- .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
- .isEqualTo(NO_SIGNAL)
- else ->
- assertWithMessage("Level $i is expected not to be null")
- .that(latest)
- .isNotNull()
- }
+ fun contentDescription_nonInflated_testABunchOfLevelsForNull() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
+
+ repository.inflateSignalStrength.setValue(false)
+ repository.numberOfLevels.setValue(5)
+
+ // -1 and 5 are out of the bounds for non-inflated content descriptions
+ for (i in -1..5) {
+ repository.setAllLevels(i)
+ when (i) {
+ -1,
+ 5 ->
+ assertWithMessage("Level $i is expected to be null")
+ .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+ .isEqualTo(NO_SIGNAL)
+ else ->
+ assertWithMessage("Level $i is expected not to be null")
+ .that(latest)
+ .isNotNull()
}
}
+ }
@Test
- fun contentDescription_inflated_testABunchOfLevelsForNull() =
- testScope.runTest {
- val latest by collectLastValue(underTest.contentDescription)
- repository.inflateSignalStrength.value = true
- repository.numberOfLevels.value = 6
- // -1 and 6 are out of the bounds for inflated content descriptions
- // Note that the interactor adds 1 to the reported level, hence the -2 to 5 range
- for (i in -2..5) {
- repository.setAllLevels(i)
- when (i) {
- -2,
- 5 ->
- assertWithMessage("Level $i is expected to be 'no signal'")
- .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
- .isEqualTo(NO_SIGNAL)
- else ->
- assertWithMessage("Level $i is not expected to be null")
- .that(latest)
- .isNotNull()
- }
+ fun contentDescription_inflated_testABunchOfLevelsForNull() = runTest {
+ val latest by underTest.contentDescription.collectLastValue()
+ repository.inflateSignalStrength.setValue(true)
+ repository.numberOfLevels.setValue(6)
+ // -1 and 6 are out of the bounds for inflated content descriptions
+ // Note that the interactor adds 1 to the reported level, hence the -2 to 5 range
+ for (i in -2..5) {
+ repository.setAllLevels(i)
+ when (i) {
+ -2,
+ 5 ->
+ assertWithMessage("Level $i is expected to be null")
+ .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+ .isEqualTo(NO_SIGNAL)
+ else ->
+ assertWithMessage("Level $i is not expected to be null")
+ .that(latest)
+ .isNotNull()
}
}
+ }
@Test
- fun networkType_dataEnabled_groupIsRepresented() =
- testScope.runTest {
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- connectionsRepository.mobileIsDefault.value = true
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
-
- @Test
- fun networkType_null_whenDisabled() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- repository.setDataEnabled(false)
- connectionsRepository.mobileIsDefault.value = true
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ fun networkType_dataEnabled_groupIsRepresented() = runTest {
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
- assertThat(latest).isNull()
+ val latest by underTest.networkTypeIcon.collectLastValue()
- job.cancel()
- }
+ assertThat(latest).isEqualTo(expected)
+ }
@Test
- fun networkType_null_whenCarrierNetworkChangeActive() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- repository.carrierNetworkChangeActive.value = true
- connectionsRepository.mobileIsDefault.value = true
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- assertThat(latest).isNull()
+ fun networkType_null_whenDisabled() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ repository.dataEnabled.setValue(false)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- job.cancel()
- }
+ assertThat(latest).isNull()
+ }
@Test
- fun networkTypeIcon_notNull_whenEnabled() =
- testScope.runTest {
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- repository.setDataEnabled(true)
- repository.dataConnectionState.value = DataConnectionState.Connected
- connectionsRepository.mobileIsDefault.value = true
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
+ fun networkType_null_whenCarrierNetworkChangeActive() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ repository.carrierNetworkChangeActive.setValue(true)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+ val latest by underTest.networkTypeIcon.collectLastValue()
+
+ assertThat(latest).isNull()
+ }
@Test
- fun networkType_nullWhenDataDisconnects() =
- testScope.runTest {
- val initial =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
+ fun networkTypeIcon_notNull_whenEnabled() = runTest {
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ repository.dataEnabled.setValue(true)
+ repository.dataConnectionState.setValue(DataConnectionState.Connected)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ assertThat(latest).isEqualTo(expected)
+ }
- assertThat(latest).isEqualTo(initial)
+ @Test
+ fun networkType_nullWhenDataDisconnects() = runTest {
+ val initial =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
- repository.dataConnectionState.value = DataConnectionState.Disconnected
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- assertThat(latest).isNull()
+ assertThat(latest).isEqualTo(initial)
- job.cancel()
- }
+ repository.dataConnectionState.setValue(DataConnectionState.Disconnected)
- @Test
- fun networkType_null_changeToDisabled() =
- testScope.runTest {
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- repository.dataEnabled.value = true
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ assertThat(latest).isNull()
+ }
- assertThat(latest).isEqualTo(expected)
+ @Test
+ fun networkType_null_changeToDisabled() = runTest {
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ repository.dataEnabled.setValue(true)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- repository.dataEnabled.value = false
+ assertThat(latest).isEqualTo(expected)
- assertThat(latest).isNull()
+ repository.dataEnabled.setValue(false)
- job.cancel()
- }
+ assertThat(latest).isNull()
+ }
@Test
- fun networkType_alwaysShow_shownEvenWhenDisabled() =
- testScope.runTest {
- repository.dataEnabled.value = false
-
- connectionsRepository.defaultDataSubRatConfig.value =
- MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ fun networkType_alwaysShow_shownEvenWhenDisabled() = runTest {
+ repository.dataEnabled.setValue(false)
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+ MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ )
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- assertThat(latest).isEqualTo(expected)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- job.cancel()
- }
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ assertThat(latest).isEqualTo(expected)
+ }
@Test
- fun networkType_alwaysShow_shownEvenWhenDisconnected() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- repository.dataConnectionState.value = DataConnectionState.Disconnected
+ fun networkType_alwaysShow_shownEvenWhenDisconnected() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ repository.dataConnectionState.setValue(DataConnectionState.Disconnected)
- connectionsRepository.defaultDataSubRatConfig.value =
- MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+ MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ )
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ assertThat(latest).isEqualTo(expected)
+ }
@Test
- fun networkType_alwaysShow_shownEvenWhenFailedConnection() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- connectionsRepository.mobileIsDefault.value = true
- connectionsRepository.defaultDataSubRatConfig.value =
- MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
-
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
+ fun networkType_alwaysShow_shownEvenWhenFailedConnection() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+ mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+ MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ )
- @Test
- fun networkType_alwaysShow_usesDefaultIconWhenInvalid() =
- testScope.runTest {
- // The UNKNOWN icon group doesn't have a valid data type icon ID, and the logic from the
- // old pipeline was to use the default icon group if the map doesn't exist
- repository.setNetworkTypeKey(UNKNOWN.name)
- connectionsRepository.defaultDataSubRatConfig.value =
- MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
-
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- val expected =
- Icon.Resource(
- connectionsRepository.defaultMobileIconGroup.value.dataType,
- ContentDescription.Resource(G.dataContentDescription),
- )
-
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
+ val latest by underTest.networkTypeIcon.collectLastValue()
- @Test
- fun networkType_alwaysShow_shownWhenNotDefault() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- connectionsRepository.mobileIsDefault.value = false
- connectionsRepository.defaultDataSubRatConfig.value =
- MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
-
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
-
- val expected =
- Icon.Resource(
- THREE_G.dataType,
- ContentDescription.Resource(THREE_G.dataContentDescription),
- )
- assertThat(latest).isEqualTo(expected)
-
- job.cancel()
- }
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ assertThat(latest).isEqualTo(expected)
+ }
@Test
- fun networkType_notShownWhenNotDefault() =
- testScope.runTest {
- repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
- repository.dataConnectionState.value = DataConnectionState.Connected
- connectionsRepository.mobileIsDefault.value = false
+ fun networkType_alwaysShow_usesDefaultIconWhenInvalid() = runTest {
+ // The UNKNOWN icon group doesn't have a valid data type icon ID, and the logic from the
+ // old pipeline was to use the default icon group if the map doesn't exist
+ repository.setNetworkTypeKey(UNKNOWN.name)
+ mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+ MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ )
- var latest: Icon? = null
- val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- assertThat(latest).isNull()
+ val expected =
+ Icon.Resource(
+ kairos.transact {
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.sample().dataType
+ },
+ ContentDescription.Resource(G.dataContentDescription),
+ )
- job.cancel()
- }
+ assertThat(latest).isEqualTo(expected)
+ }
@Test
- fun roaming() =
- testScope.runTest {
- repository.setAllRoaming(true)
+ fun networkType_alwaysShow_shownWhenNotDefault() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(false)
+ mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+ MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+ )
- var latest: Boolean? = null
- val job = underTest.roaming.onEach { latest = it }.launchIn(this)
+ val latest by underTest.networkTypeIcon.collectLastValue()
- assertThat(latest).isTrue()
+ val expected =
+ Icon.Resource(
+ THREE_G.dataType,
+ ContentDescription.Resource(THREE_G.dataContentDescription),
+ )
+ assertThat(latest).isEqualTo(expected)
+ }
- repository.setAllRoaming(false)
+ @Test
+ fun networkType_notShownWhenNotDefault() = runTest {
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ repository.dataConnectionState.setValue(DataConnectionState.Connected)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(false)
- assertThat(latest).isFalse()
+ val latest by underTest.networkTypeIcon.collectLastValue()
- job.cancel()
- }
+ assertThat(latest).isNull()
+ }
@Test
- fun dataActivity_nullWhenConfigIsOff() =
- testScope.runTest {
- // Create a new view model here so the constants are properly read
- whenever(constants.shouldShowActivityConfig).thenReturn(false)
- createAndSetViewModel()
+ fun roaming() = runTest {
+ repository.setAllRoaming(true)
- var inVisible: Boolean? = null
- val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+ val latest by underTest.roaming.collectLastValue()
- var outVisible: Boolean? = null
- val outJob = underTest.activityInVisible.onEach { outVisible = it }.launchIn(this)
+ assertThat(latest).isTrue()
- var containerVisible: Boolean? = null
- val containerJob =
- underTest.activityInVisible.onEach { containerVisible = it }.launchIn(this)
+ repository.setAllRoaming(false)
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+ assertThat(latest).isFalse()
+ }
- assertThat(inVisible).isFalse()
- assertThat(outVisible).isFalse()
- assertThat(containerVisible).isFalse()
+ @Test
+ fun dataActivity_nullWhenConfigIsOff() = runTest {
+ constants.stub { on { shouldShowActivityConfig } doReturn false }
- inJob.cancel()
- outJob.cancel()
- containerJob.cancel()
- }
+ val inVisible by underTest.activityInVisible.collectLastValue()
+
+ val outVisible by underTest.activityInVisible.collectLastValue()
+
+ val containerVisible by underTest.activityInVisible.collectLastValue()
+
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+ )
+
+ assertThat(inVisible).isFalse()
+ assertThat(outVisible).isFalse()
+ assertThat(containerVisible).isFalse()
+ }
@Test
@DisableFlags(FLAG_STATUS_BAR_STATIC_INOUT_INDICATORS)
- fun dataActivity_configOn_testIndicators_staticFlagOff() =
- testScope.runTest {
- // Create a new view model here so the constants are properly read
- whenever(constants.shouldShowActivityConfig).thenReturn(true)
- createAndSetViewModel()
+ fun dataActivity_configOn_testIndicators_staticFlagOff() = runTest {
+ constants.stub { on { shouldShowActivityConfig } doReturn true }
- var inVisible: Boolean? = null
- val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+ val inVisible by underTest.activityInVisible.collectLastValue()
- var outVisible: Boolean? = null
- val outJob = underTest.activityOutVisible.onEach { outVisible = it }.launchIn(this)
+ val outVisible by underTest.activityOutVisible.collectLastValue()
- var containerVisible: Boolean? = null
- val containerJob =
- underTest.activityContainerVisible.onEach { containerVisible = it }.launchIn(this)
+ val containerVisible by underTest.activityContainerVisible.collectLastValue()
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+ )
- yield()
+ yield()
- assertThat(inVisible).isTrue()
- assertThat(outVisible).isFalse()
- assertThat(containerVisible).isTrue()
+ assertThat(inVisible).isTrue()
+ assertThat(outVisible).isFalse()
+ assertThat(containerVisible).isTrue()
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+ )
- assertThat(inVisible).isFalse()
- assertThat(outVisible).isTrue()
- assertThat(containerVisible).isTrue()
+ assertThat(inVisible).isFalse()
+ assertThat(outVisible).isTrue()
+ assertThat(containerVisible).isTrue()
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+ )
- assertThat(inVisible).isFalse()
- assertThat(outVisible).isFalse()
- assertThat(containerVisible).isFalse()
-
- inJob.cancel()
- outJob.cancel()
- containerJob.cancel()
- }
+ assertThat(inVisible).isFalse()
+ assertThat(outVisible).isFalse()
+ assertThat(containerVisible).isFalse()
+ }
@Test
@EnableFlags(FLAG_STATUS_BAR_STATIC_INOUT_INDICATORS)
- fun dataActivity_configOn_testIndicators_staticFlagOn() =
- testScope.runTest {
- // Create a new view model here so the constants are properly read
- whenever(constants.shouldShowActivityConfig).thenReturn(true)
- createAndSetViewModel()
-
- var inVisible: Boolean? = null
- val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+ fun dataActivity_configOn_testIndicators_staticFlagOn() = runTest {
+ constants.stub { on { shouldShowActivityConfig } doReturn true }
- var outVisible: Boolean? = null
- val outJob = underTest.activityOutVisible.onEach { outVisible = it }.launchIn(this)
+ val inVisible by underTest.activityInVisible.collectLastValue()
- var containerVisible: Boolean? = null
- val containerJob =
- underTest.activityContainerVisible.onEach { containerVisible = it }.launchIn(this)
+ val outVisible by underTest.activityOutVisible.collectLastValue()
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+ val containerVisible by underTest.activityContainerVisible.collectLastValue()
- yield()
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+ )
- assertThat(inVisible).isTrue()
- assertThat(outVisible).isFalse()
- assertThat(containerVisible).isTrue()
+ yield()
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+ assertThat(inVisible).isTrue()
+ assertThat(outVisible).isFalse()
+ assertThat(containerVisible).isTrue()
- assertThat(inVisible).isFalse()
- assertThat(outVisible).isTrue()
- assertThat(containerVisible).isTrue()
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+ )
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+ assertThat(inVisible).isFalse()
+ assertThat(outVisible).isTrue()
+ assertThat(containerVisible).isTrue()
- assertThat(inVisible).isFalse()
- assertThat(outVisible).isFalse()
- assertThat(containerVisible).isTrue()
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+ )
- inJob.cancel()
- outJob.cancel()
- containerJob.cancel()
- }
+ assertThat(inVisible).isFalse()
+ assertThat(outVisible).isFalse()
+ assertThat(containerVisible).isTrue()
+ }
@Test
- fun netTypeBackground_nullWhenNoPrioritizedCapabilities() =
- testScope.runTest {
- createAndSetViewModel()
-
- val latest by collectLastValue(underTest.networkTypeBackground)
+ fun netTypeBackground_nullWhenNoPrioritizedCapabilities() = runTest {
+ val latest by underTest.networkTypeBackground.collectLastValue()
- repository.hasPrioritizedNetworkCapabilities.value = false
+ repository.hasPrioritizedNetworkCapabilities.setValue(false)
- assertThat(latest).isNull()
- }
+ assertThat(latest).isNull()
+ }
@Test
@EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
- fun netTypeBackground_sliceUiEnabled_notNullWhenPrioritizedCapabilities_newIcons() =
- testScope.runTest {
- createAndSetViewModel()
+ fun netTypeBackground_sliceUiEnabled_notNullWhenPrioritizedCapabilities_newIcons() = runTest {
+ val latest by underTest.networkTypeBackground.collectLastValue()
- val latest by collectLastValue(underTest.networkTypeBackground)
+ repository.hasPrioritizedNetworkCapabilities.setValue(true)
- repository.hasPrioritizedNetworkCapabilities.value = true
-
- assertThat(latest)
- .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background_updated, null))
- }
+ assertThat(latest)
+ .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background_updated, null))
+ }
@Test
@DisableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
- fun netTypeBackground_sliceUiDisabled_notNullWhenPrioritizedCapabilities_oldIcons() =
- testScope.runTest {
- createAndSetViewModel()
-
- val latest by collectLastValue(underTest.networkTypeBackground)
+ fun netTypeBackground_sliceUiDisabled_notNullWhenPrioritizedCapabilities_oldIcons() = runTest {
+ val latest by underTest.networkTypeBackground.collectLastValue()
- repository.hasPrioritizedNetworkCapabilities.value = true
+ repository.allowNetworkSliceIndicator.setValue(true)
+ repository.hasPrioritizedNetworkCapabilities.setValue(true)
- assertThat(latest)
- .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background, null))
- }
+ assertThat(latest).isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background, null))
+ }
@Test
- fun nonTerrestrial_defaultProperties() =
- testScope.runTest {
- repository.isNonTerrestrial.value = true
-
- val roaming by collectLastValue(underTest.roaming)
- val networkTypeIcon by collectLastValue(underTest.networkTypeIcon)
- val networkTypeBackground by collectLastValue(underTest.networkTypeBackground)
- val activityInVisible by collectLastValue(underTest.activityInVisible)
- val activityOutVisible by collectLastValue(underTest.activityOutVisible)
- val activityContainerVisible by collectLastValue(underTest.activityContainerVisible)
-
- assertThat(roaming).isFalse()
- assertThat(networkTypeIcon).isNull()
- assertThat(networkTypeBackground).isNull()
- assertThat(activityInVisible).isFalse()
- assertThat(activityOutVisible).isFalse()
- assertThat(activityContainerVisible).isFalse()
- }
+ fun nonTerrestrial_defaultProperties() = runTest {
+ repository.isNonTerrestrial.setValue(true)
+
+ val roaming by underTest.roaming.collectLastValue()
+ val networkTypeIcon by underTest.networkTypeIcon.collectLastValue()
+ val networkTypeBackground by underTest.networkTypeBackground.collectLastValue()
+ val activityInVisible by underTest.activityInVisible.collectLastValue()
+ val activityOutVisible by underTest.activityOutVisible.collectLastValue()
+ val activityContainerVisible by underTest.activityContainerVisible.collectLastValue()
+
+ assertThat(roaming).isFalse()
+ assertThat(networkTypeIcon).isNull()
+ assertThat(networkTypeBackground).isNull()
+ assertThat(activityInVisible).isFalse()
+ assertThat(activityOutVisible).isFalse()
+ assertThat(activityContainerVisible).isFalse()
+ }
@Test
- fun nonTerrestrial_ignoresDefaultProperties() =
- testScope.runTest {
- repository.isNonTerrestrial.value = true
-
- val roaming by collectLastValue(underTest.roaming)
- val networkTypeIcon by collectLastValue(underTest.networkTypeIcon)
- val networkTypeBackground by collectLastValue(underTest.networkTypeBackground)
- val activityInVisible by collectLastValue(underTest.activityInVisible)
- val activityOutVisible by collectLastValue(underTest.activityOutVisible)
- val activityContainerVisible by collectLastValue(underTest.activityContainerVisible)
-
- repository.setAllRoaming(true)
- repository.setNetworkTypeKey(connectionsRepository.LTE_KEY)
- // sets the background on cellular
- repository.hasPrioritizedNetworkCapabilities.value = true
- repository.dataActivityDirection.value =
- DataActivityModel(hasActivityIn = true, hasActivityOut = true)
-
- assertThat(roaming).isFalse()
- assertThat(networkTypeIcon).isNull()
- assertThat(networkTypeBackground).isNull()
- assertThat(activityInVisible).isFalse()
- assertThat(activityOutVisible).isFalse()
- assertThat(activityContainerVisible).isFalse()
- }
+ fun nonTerrestrial_ignoresDefaultProperties() = runTest {
+ repository.isNonTerrestrial.setValue(true)
+
+ val roaming by underTest.roaming.collectLastValue()
+ val networkTypeIcon by underTest.networkTypeIcon.collectLastValue()
+ val networkTypeBackground by underTest.networkTypeBackground.collectLastValue()
+ val activityInVisible by underTest.activityInVisible.collectLastValue()
+ val activityOutVisible by underTest.activityOutVisible.collectLastValue()
+ val activityContainerVisible by underTest.activityContainerVisible.collectLastValue()
+
+ repository.setAllRoaming(true)
+ repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.LTE_KEY)
+ // sets the background on cellular
+ repository.hasPrioritizedNetworkCapabilities.setValue(true)
+ repository.dataActivityDirection.setValue(
+ DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+ )
+
+ assertThat(roaming).isFalse()
+ assertThat(networkTypeIcon).isNull()
+ assertThat(networkTypeBackground).isNull()
+ assertThat(activityInVisible).isFalse()
+ assertThat(activityOutVisible).isFalse()
+ assertThat(activityContainerVisible).isFalse()
+ }
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
- fun nonTerrestrial_usesSatelliteIcon_flagOff() =
- testScope.runTest {
- repository.isNonTerrestrial.value = true
- repository.setAllLevels(0)
- repository.satelliteLevel.value = 0
-
- val latest by
- collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
-
- // Level 0 -> no connection
- assertThat(latest).isNotNull()
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
-
- // 1-2 -> 1 bar
- repository.setAllLevels(1)
- repository.satelliteLevel.value = 1
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- repository.setAllLevels(2)
- repository.satelliteLevel.value = 2
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- // 3-4 -> 2 bars
- repository.setAllLevels(3)
- repository.satelliteLevel.value = 3
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-
- repository.setAllLevels(4)
- repository.satelliteLevel.value = 4
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
- }
+ fun nonTerrestrial_usesSatelliteIcon_flagOff() = runTest {
+ repository.isNonTerrestrial.setValue(true)
+ repository.setAllLevels(0)
+ repository.satelliteLevel.setValue(0)
+
+ val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
+
+ // Level 0 -> no connection
+ assertThat(latest).isNotNull()
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+
+ // 1-2 -> 1 bar
+ repository.setAllLevels(1)
+ repository.satelliteLevel.setValue(1)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ repository.setAllLevels(2)
+ repository.satelliteLevel.setValue(2)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ // 3-4 -> 2 bars
+ repository.setAllLevels(3)
+ repository.satelliteLevel.setValue(3)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+
+ repository.setAllLevels(4)
+ repository.satelliteLevel.setValue(4)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+ }
@EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
- fun nonTerrestrial_usesSatelliteIcon_flagOn() =
- testScope.runTest {
- repository.isNonTerrestrial.value = true
- repository.satelliteLevel.value = 0
+ fun nonTerrestrial_usesSatelliteIcon_flagOn() = runTest {
+ repository.isNonTerrestrial.setValue(true)
+ repository.satelliteLevel.setValue(0)
- val latest by
- collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+ val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
- // Level 0 -> no connection
- assertThat(latest).isNotNull()
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+ // Level 0 -> no connection
+ assertThat(latest).isNotNull()
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
- // 1-2 -> 1 bar
- repository.satelliteLevel.value = 1
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+ // 1-2 -> 1 bar
+ repository.satelliteLevel.setValue(1)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
- repository.satelliteLevel.value = 2
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+ repository.satelliteLevel.setValue(2)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
- // 3-4 -> 2 bars
- repository.satelliteLevel.value = 3
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+ // 3-4 -> 2 bars
+ repository.satelliteLevel.setValue(3)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
- repository.satelliteLevel.value = 4
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
- }
+ repository.satelliteLevel.setValue(4)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+ }
@DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
- fun satelliteIcon_ignoresInflateSignalStrength_flagOff() =
- testScope.runTest {
- // Note that this is the exact same test as above, but with inflateSignalStrength set to
- // true we note that the level is unaffected by inflation
- repository.inflateSignalStrength.value = true
- repository.isNonTerrestrial.value = true
- repository.setAllLevels(0)
- repository.satelliteLevel.value = 0
-
- val latest by
- collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
-
- // Level 0 -> no connection
- assertThat(latest).isNotNull()
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
-
- // 1-2 -> 1 bar
- repository.setAllLevels(1)
- repository.satelliteLevel.value = 1
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- repository.setAllLevels(2)
- repository.satelliteLevel.value = 2
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- // 3-4 -> 2 bars
- repository.setAllLevels(3)
- repository.satelliteLevel.value = 3
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-
- repository.setAllLevels(4)
- repository.satelliteLevel.value = 4
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
- }
+ fun satelliteIcon_ignoresInflateSignalStrength_flagOff() = runTest {
+ // Note that this is the exact same test as above, but with inflateSignalStrength set to
+ // true we note that the level is unaffected by inflation
+ repository.inflateSignalStrength.setValue(true)
+ repository.isNonTerrestrial.setValue(true)
+ repository.setAllLevels(0)
+ repository.satelliteLevel.setValue(0)
+
+ val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
+
+ // Level 0 -> no connection
+ assertThat(latest).isNotNull()
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+
+ // 1-2 -> 1 bar
+ repository.setAllLevels(1)
+ repository.satelliteLevel.setValue(1)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ repository.setAllLevels(2)
+ repository.satelliteLevel.setValue(2)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ // 3-4 -> 2 bars
+ repository.setAllLevels(3)
+ repository.satelliteLevel.setValue(3)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+
+ repository.setAllLevels(4)
+ repository.satelliteLevel.setValue(4)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+ }
@EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
@Test
- fun satelliteIcon_ignoresInflateSignalStrength_flagOn() =
- testScope.runTest {
- // Note that this is the exact same test as above, but with inflateSignalStrength set to
- // true we note that the level is unaffected by inflation
- repository.inflateSignalStrength.value = true
- repository.isNonTerrestrial.value = true
- repository.satelliteLevel.value = 0
-
- val latest by
- collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
-
- // Level 0 -> no connection
- assertThat(latest).isNotNull()
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
-
- // 1-2 -> 1 bar
- repository.satelliteLevel.value = 1
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- repository.satelliteLevel.value = 2
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
-
- // 3-4 -> 2 bars
- repository.satelliteLevel.value = 3
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-
- repository.satelliteLevel.value = 4
- assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
- }
+ fun satelliteIcon_ignoresInflateSignalStrength_flagOn() = runTest {
+ // Note that this is the exact same test as above, but with inflateSignalStrength set to
+ // true we note that the level is unaffected by inflation
+ repository.inflateSignalStrength.setValue(true)
+ repository.isNonTerrestrial.setValue(true)
+ repository.satelliteLevel.setValue(0)
- private fun createAndSetViewModel() {
- underTest =
- MobileIconViewModelKairos(
- SUB_1_ID,
- interactor,
- airplaneModeInteractor,
- constants,
- testScope.backgroundScope,
- )
+ val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
+
+ // Level 0 -> no connection
+ assertThat(latest).isNotNull()
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+
+ // 1-2 -> 1 bar
+ repository.satelliteLevel.setValue(1)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ repository.satelliteLevel.setValue(2)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+
+ // 3-4 -> 2 bars
+ repository.satelliteLevel.setValue(3)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+
+ repository.satelliteLevel.setValue(4)
+ assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
}
companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
index e921430394c2..b11bad6f3ad3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -16,348 +16,323 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
-import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
-import junit.framework.Assert.assertFalse
-import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class MobileIconsViewModelKairosTest : SysuiTestCase() {
- private val kosmos = testKosmos()
- private lateinit var underTest: MobileIconsViewModelKairos
- private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
- private val flags = FakeFeatureFlagsClassic()
-
- private lateinit var airplaneModeInteractor: AirplaneModeInteractor
- @Mock private lateinit var constants: ConnectivityConstants
- @Mock private lateinit var logger: MobileViewLogger
- @Mock private lateinit var verboseLogger: VerboseMobileViewLogger
-
- private val testDispatcher = UnconfinedTestDispatcher()
- private val testScope = TestScope(testDispatcher)
+ private val Kosmos.underTest
+ get() = mobileIconsViewModelKairos
+
+ private val kosmos =
+ testKosmos().apply {
+ useUnconfinedTestDispatcher()
+ featureFlagsClassic.fake.apply {
+ setDefault(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS)
+ }
+ mobileConnectionsRepositoryKairos =
+ fakeMobileConnectionsRepositoryKairos.apply {
+ val subList = listOf(SUB_1, SUB_2)
+ setActiveMobileDataSubscriptionId(SUB_1.subscriptionId)
+ subscriptions.setValue(subList)
+ }
+ }
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
+ private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+ kosmos.run { runKairosTest { block() } }
+
+ private fun KairosTestScope.setSubscriptions(
+ subList: List<SubscriptionModel>,
+ activeSubId: Int = subList.getOrNull(0)?.subscriptionId ?: INVALID_SUBSCRIPTION_ID,
+ ) {
+ println("setSubscriptions: mobileConnectionsRepositoryKairos.fake.subscriptions")
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(subList)
+ println(
+ "setSubscriptions: mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId"
+ )
+ mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(activeSubId)
+ }
- airplaneModeInteractor =
- AirplaneModeInteractor(
- FakeAirplaneModeRepository(),
- FakeConnectivityRepository(),
- kosmos.fakeMobileConnectionsRepository,
+ @Test
+ fun subscriptionIdsFlow_matchesInteractor() = runTest {
+ val latest by underTest.subscriptionIds.collectLastValue()
+ setSubscriptions(
+ listOf(
+ SubscriptionModel(
+ subscriptionId = 1,
+ isOpportunistic = false,
+ carrierName = "Carrier 1",
+ profileClass = PROFILE_CLASS_UNSET,
+ )
)
-
- underTest =
- MobileIconsViewModelKairos(
- logger,
- verboseLogger,
- interactor,
- airplaneModeInteractor,
- constants,
- testScope.backgroundScope,
+ )
+ assertThat(latest).isEqualTo(listOf(1))
+
+ setSubscriptions(
+ listOf(
+ SubscriptionModel(
+ subscriptionId = 2,
+ isOpportunistic = false,
+ carrierName = "Carrier 2",
+ profileClass = PROFILE_CLASS_UNSET,
+ ),
+ SubscriptionModel(
+ subscriptionId = 5,
+ isOpportunistic = true,
+ carrierName = "Carrier 5",
+ profileClass = PROFILE_CLASS_UNSET,
+ ),
+ SubscriptionModel(
+ subscriptionId = 7,
+ isOpportunistic = true,
+ carrierName = "Carrier 7",
+ profileClass = PROFILE_CLASS_UNSET,
+ ),
)
+ )
+ assertThat(latest).isEqualTo(listOf(2, 5, 7))
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+ setSubscriptions(emptyList())
+ assertThat(latest).isEmpty()
}
@Test
- fun subscriptionIdsFlow_matchesInteractor() =
- testScope.runTest {
- var latest: List<Int>? = null
- val job = underTest.subscriptionIdsFlow.onEach { latest = it }.launchIn(this)
-
- interactor.filteredSubscriptions.value =
- listOf(
- SubscriptionModel(
- subscriptionId = 1,
- isOpportunistic = false,
- carrierName = "Carrier 1",
- profileClass = PROFILE_CLASS_UNSET,
- )
- )
- assertThat(latest).isEqualTo(listOf(1))
-
- interactor.filteredSubscriptions.value =
- listOf(
- SubscriptionModel(
- subscriptionId = 2,
- isOpportunistic = false,
- carrierName = "Carrier 2",
- profileClass = PROFILE_CLASS_UNSET,
- ),
- SubscriptionModel(
- subscriptionId = 5,
- isOpportunistic = true,
- carrierName = "Carrier 5",
- profileClass = PROFILE_CLASS_UNSET,
- ),
- SubscriptionModel(
- subscriptionId = 7,
- isOpportunistic = true,
- carrierName = "Carrier 7",
- profileClass = PROFILE_CLASS_UNSET,
- ),
- )
- assertThat(latest).isEqualTo(listOf(2, 5, 7))
+ fun firstMobileSubShowingNetworkTypeIcon_noSubs_false() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- interactor.filteredSubscriptions.value = emptyList()
- assertThat(latest).isEmpty()
+ setSubscriptions(emptyList())
- job.cancel()
- }
+ assertThat(latest).isEqualTo(false)
+ }
@Test
- fun caching_mobileIconViewModelIsReusedForSameSubId() =
- testScope.runTest {
- val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
- val model2 = underTest.viewModelForSub(1, StatusBarLocation.QS)
+ fun firstMobileSubShowingNetworkTypeIcon_oneSub_notShowingRat_false() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- assertThat(model1.commonImpl).isSameInstanceAs(model2.commonImpl)
- }
+ setSubscriptions(listOf(SUB_1))
+
+ // The unknown icon group doesn't show a RAT
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]
+ ?.resolvedNetworkType
+ ?.setValue(UnknownNetworkType)
+
+ assertThat(latest).isFalse()
+ }
@Test
- fun caching_invalidViewModelsAreRemovedFromCacheWhenSubDisappears() =
- testScope.runTest {
- // Retrieve models to trigger caching
- val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
- val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS)
+ fun firstMobileSubShowingNetworkTypeIcon_oneSub_showingRat_true() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
+ setSubscriptions(listOf(SUB_1))
- // Both impls are cached
- assertThat(underTest.reuseCache.keys).containsExactly(1, 2)
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- // SUB_1 is removed from the list...
- interactor.filteredSubscriptions.value = listOf(SUB_2)
+ // The 3G icon group will show a RAT
+ val repo =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
- // ... and dropped from the cache
- assertThat(underTest.reuseCache.keys).containsExactly(2)
- }
+ repo.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
+ repo.dataConnectionState.setValue(DataConnectionState.Connected)
+
+ assertThat(latest).isEqualTo(true)
+ }
@Test
- fun caching_invalidatedViewModelsAreCanceled() =
- testScope.runTest {
- // Retrieve models to trigger caching
- val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
- val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS)
+ fun firstMobileSubShowingNetworkTypeIcon_updatesAsSubUpdates() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
+ setSubscriptions(listOf(SUB_1))
- var scope1 = underTest.reuseCache[1]?.second
- var scope2 = underTest.reuseCache[2]?.second
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- // Scopes are not canceled
- assertTrue(scope1!!.isActive)
- assertTrue(scope2!!.isActive)
+ val repo =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
- // SUB_1 is removed from the list...
- interactor.filteredSubscriptions.value = listOf(SUB_2)
+ repo.dataConnectionState.setValue(DataConnectionState.Connected)
- // scope1 is canceled
- assertFalse(scope1!!.isActive)
- assertTrue(scope2!!.isActive)
- }
+ repo.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
+ assertThat(latest).isEqualTo(true)
+
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+ TelephonyIcons.UNKNOWN
+ )
+
+ repo.resolvedNetworkType.setValue(UnknownNetworkType)
+ assertThat(latest).isEqualTo(false)
+
+ repo.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.LTE_KEY)
+ )
+ assertThat(latest).isEqualTo(true)
+ }
@Test
- fun firstMobileSubShowingNetworkTypeIcon_noSubs_false() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+ fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubNotShowingRat_false() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- interactor.filteredSubscriptions.value = emptyList()
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+ TelephonyIcons.UNKNOWN
+ )
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- assertThat(latest).isFalse()
+ val repo1 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
- job.cancel()
- }
+ repo1.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
+
+ val repo2 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_2.subscriptionId]!!
+
+ repo2.resolvedNetworkType.setValue(UnknownNetworkType)
+
+ assertThat(latest).isFalse()
+ }
@Test
- fun firstMobileSubShowingNetworkTypeIcon_oneSub_notShowingRat_false() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+ fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubShowingRat_true() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- interactor.filteredSubscriptions.value = listOf(SUB_1)
- // The unknown icon group doesn't show a RAT
- interactor.getInteractorForSubId(1)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+ TelephonyIcons.UNKNOWN
+ )
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- assertThat(latest).isFalse()
+ val repo1 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
- job.cancel()
- }
+ repo1.dataConnectionState.setValue(DataConnectionState.Connected)
+ repo1.resolvedNetworkType.setValue(UnknownNetworkType)
+
+ val repo2 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_2.subscriptionId]!!
+
+ repo2.dataConnectionState.setValue(DataConnectionState.Connected)
+ repo2.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
+
+ assertThat(latest).isEqualTo(true)
+ }
@Test
- fun firstMobileSubShowingNetworkTypeIcon_oneSub_showingRat_true() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+ fun firstMobileSubShowingNetworkTypeIcon_subListUpdates_valAlsoUpdates() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- interactor.filteredSubscriptions.value = listOf(SUB_1)
- // The 3G icon group will show a RAT
- interactor.getInteractorForSubId(1)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+ TelephonyIcons.UNKNOWN
+ )
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- assertThat(latest).isTrue()
+ val repo1 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
- job.cancel()
- }
+ repo1.dataConnectionState.setValue(DataConnectionState.Connected)
+ repo1.resolvedNetworkType.setValue(UnknownNetworkType)
- @Test
- fun firstMobileSubShowingNetworkTypeIcon_updatesAsSubUpdates() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+ val repo2 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_2.subscriptionId]!!
- interactor.filteredSubscriptions.value = listOf(SUB_1)
- val sub1Interactor = interactor.getInteractorForSubId(1)!!
+ repo2.dataConnectionState.setValue(DataConnectionState.Connected)
+ repo2.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
- sub1Interactor.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
- assertThat(latest).isTrue()
+ assertThat(latest).isEqualTo(true)
- sub1Interactor.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
- assertThat(latest).isFalse()
+ // WHEN the sub list gets new subscriptions where the last subscription is not showing
+ // the network type icon
+ setSubscriptions(listOf(SUB_1, SUB_2, SUB_3))
- sub1Interactor.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.LTE)
- assertThat(latest).isTrue()
+ val repo3 =
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_3.subscriptionId]!!
- job.cancel()
- }
+ repo3.dataConnectionState.setValue(DataConnectionState.Connected)
+ repo3.resolvedNetworkType.setValue(UnknownNetworkType)
+
+ // THEN the flow updates
+ assertThat(latest).isEqualTo(false)
+ }
@Test
- fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubNotShowingRat_false() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+ fun firstMobileSubShowingNetworkTypeIcon_subListReorders_valAlsoUpdates() = runTest {
+ val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
- interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
- interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
+ mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+ TelephonyIcons.UNKNOWN
+ )
+ mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
- assertThat(latest).isFalse()
+ setSubscriptions(listOf(SUB_1, SUB_2))
+ // Immediately switch the order so that we've created both interactors
+ setSubscriptions(listOf(SUB_2, SUB_1))
- job.cancel()
- }
+ val repos = mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId.sample()
+ val repo1 = repos[SUB_1.subscriptionId]!!
+ repo1.dataConnectionState.setValue(DataConnectionState.Connected)
- @Test
- fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubShowingRat_true() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
-
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
- interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
- interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
-
- assertThat(latest).isTrue()
- job.cancel()
- }
+ val repo2 = repos[SUB_2.subscriptionId]!!
+ repo2.dataConnectionState.setValue(DataConnectionState.Connected)
- @Test
- fun firstMobileSubShowingNetworkTypeIcon_subListUpdates_valAlsoUpdates() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
-
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
- interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
- interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
-
- assertThat(latest).isTrue()
-
- // WHEN the sub list gets new subscriptions where the last subscription is not showing
- // the network type icon
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2, SUB_3)
- interactor.getInteractorForSubId(3)!!.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-
- // THEN the flow updates
- assertThat(latest).isFalse()
-
- job.cancel()
- }
+ setSubscriptions(listOf(SUB_1, SUB_2))
+ repo1.resolvedNetworkType.setValue(UnknownNetworkType)
+ repo2.resolvedNetworkType.setValue(
+ DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+ )
- @Test
- fun firstMobileSubShowingNetworkTypeIcon_subListReorders_valAlsoUpdates() =
- testScope.runTest {
- var latest: Boolean? = null
- val job =
- underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
-
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
- // Immediately switch the order so that we've created both interactors
- interactor.filteredSubscriptions.value = listOf(SUB_2, SUB_1)
- val sub1Interactor = interactor.getInteractorForSubId(1)!!
- val sub2Interactor = interactor.getInteractorForSubId(2)!!
-
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
- sub1Interactor.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
- sub2Interactor.networkTypeIconGroup.value =
- NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
- assertThat(latest).isTrue()
-
- // WHEN sub1 becomes last and sub1 has no network type icon
- interactor.filteredSubscriptions.value = listOf(SUB_2, SUB_1)
-
- // THEN the flow updates
- assertThat(latest).isFalse()
-
- // WHEN sub2 becomes last and sub2 has a network type icon
- interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-
- // THEN the flow updates
- assertThat(latest).isTrue()
-
- job.cancel()
- }
+ assertThat(latest).isEqualTo(true)
+
+ // WHEN sub1 becomes last and sub1 has no network type icon
+ setSubscriptions(listOf(SUB_2, SUB_1))
+
+ // THEN the flow updates
+ assertThat(latest).isEqualTo(false)
+
+ // WHEN sub2 becomes last and sub2 has a network type icon
+ setSubscriptions(listOf(SUB_1, SUB_2))
+
+ // THEN the flow updates
+ assertThat(latest).isEqualTo(true)
+ }
companion object {
private val SUB_1 =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
index ce35d9d8610f..75f5cbb041c4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
@@ -21,81 +21,83 @@ import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.runTest
-import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
-import com.android.systemui.lifecycle.activateIn
import com.android.systemui.statusbar.core.NewStatusBarIcons
import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalKairosApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class StackedMobileIconViewModelKairosTest : SysuiTestCase() {
- private val kosmos = testKosmos().useUnconfinedTestDispatcher()
- private val testScope = kosmos.testScope
-
- private val Kosmos.underTest: StackedMobileIconViewModelKairos by Fixture {
- stackedMobileIconViewModelKairos
- }
+ private val kosmos =
+ testKosmos().useUnconfinedTestDispatcher().apply {
+ mobileConnectionsRepositoryKairos = fakeMobileConnectionsRepositoryKairos
+ featureFlagsClassic.fake.apply {
+ setDefault(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS)
+ }
+ }
- @Before
- fun setUp() {
- kosmos.underTest.activateIn(testScope)
- }
+ private val Kosmos.underTest
+ get() = stackedMobileIconViewModelKairos
@Test
@EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
fun dualSim_filtersOutNonDualConnections() =
- kosmos.runTest {
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf()
+ kosmos.runKairosTest {
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf())
assertThat(underTest.dualSim).isNull()
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1))
assertThat(underTest.dualSim).isNull()
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2, SUB_3)
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(
+ listOf(SUB_1, SUB_2, SUB_3)
+ )
assertThat(underTest.dualSim).isNull()
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
assertThat(underTest.dualSim).isNotNull()
}
@Test
@EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
fun dualSim_filtersOutNonCellularIcons() =
- kosmos.runTest {
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)
+ kosmos.runKairosTest {
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1))
assertThat(underTest.dualSim).isNull()
- fakeMobileIconsInteractor
- .getInteractorForSubId(SUB_1.subscriptionId)!!
- .signalLevelIcon
- .value =
- SignalIconModel.Satellite(
- level = 0,
- icon = Icon.Resource(res = 0, contentDescription = null),
- )
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+ .sample()[SUB_1.subscriptionId]!!
+ .apply {
+ isNonTerrestrial.setValue(true)
+ satelliteLevel.setValue(0)
+ }
+
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
assertThat(underTest.dualSim).isNull()
}
@Test
@EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
fun dualSim_tracksActiveSubId() =
- kosmos.runTest {
+ kosmos.runKairosTest {
// Active sub id is null, order is unchanged
- fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+ mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
setIconLevel(SUB_1.subscriptionId, 1)
setIconLevel(SUB_2.subscriptionId, 2)
@@ -103,16 +105,21 @@ class StackedMobileIconViewModelKairosTest : SysuiTestCase() {
assertThat(underTest.dualSim!!.secondary.level).isEqualTo(2)
// Active sub is 2, order is swapped
- fakeMobileIconsInteractor.activeMobileDataSubscriptionId.value = SUB_2.subscriptionId
+ mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(
+ SUB_2.subscriptionId
+ )
assertThat(underTest.dualSim!!.primary.level).isEqualTo(2)
assertThat(underTest.dualSim!!.secondary.level).isEqualTo(1)
}
- private fun setIconLevel(subId: Int, level: Int) {
- with(kosmos.fakeMobileIconsInteractor.getInteractorForSubId(subId)!!) {
- signalLevelIcon.value =
- (signalLevelIcon.value as SignalIconModel.Cellular).copy(level = level)
+ private suspend fun KairosTestScope.setIconLevel(subId: Int, level: Int) {
+ mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId.sample()[subId]!!.apply {
+ isNonTerrestrial.setValue(false)
+ isInService.setValue(true)
+ inflateSignalStrength.setValue(false)
+ isGsm.setValue(true)
+ primaryLevel.setValue(level)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
index d7bcf88f6941..8a7b698623f8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
@@ -45,8 +45,8 @@ class StackedMobileIconViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
- private val Kosmos.underTest: StackedMobileIconViewModel by Fixture {
- stackedMobileIconViewModel
+ private val Kosmos.underTest: StackedMobileIconViewModelImpl by Fixture {
+ stackedMobileIconViewModelImpl
}
@Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
index 3da4f29a6fcb..dc344aa1a66f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
@@ -73,7 +73,7 @@ class WindowRootViewModelTest : SysuiTestCase() {
assertThat(blurRadius).isEqualTo(0f)
- kosmos.windowRootViewBlurRepository.blurRadius.value = 60
+ kosmos.windowRootViewBlurRepository.blurRequestedByShade.value = 60
runCurrent()
assertThat(blurRadius).isEqualTo(0f)
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index fe6636bfa489..15471a69497d 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -63,8 +63,8 @@
<string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"আবার চেষ্টা করুন বা পাসওয়ার্ড লিখুন"</string>
<string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"আবার চেষ্টা করুন বা প্যাটার্ন দিন"</string>
<string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"অনেক বেশিবার চেষ্টা করার পরে পিন দিতে হবে"</string>
- <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"অনেক বেশিবার চেষ্টা করার পরে পাসওয়ার্ড দিতে হবে"</string>
- <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"অনেক বেশিবার চেষ্টা করার পরে প্যাটার্ন দিতে হবে"</string>
+ <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"অনেকবার চেষ্টা করার পর পাসওয়ার্ড দিতে হয়"</string>
+ <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"অনেকবার চেষ্টা করার পর প্যাটার্ন দিতে হয়"</string>
<string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"পিন বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
<string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"পাসওয়ার্ড বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
<string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"প্যাটার্ন বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index bc08a3e2c628..06192813672a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nuwe toestel saam te bind"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorafstelling"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Gekies"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgewing"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Wanneer jy ’n app deel, is enigiets wat in die app wys of speel, sigbaar aan <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deel skerm"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> het hierdie opsie gedeaktiveer"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Kies app om te deel"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Saai jou skerm uit?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Saai een app uit"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Sleep hierheen om te verwyder"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Jy moet minstens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> teëls hê"</string>
<string name="qs_edit" msgid="5583565172803472437">"Wysig"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tyd"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Wys ure, minute en sekondes"</item>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 64912d4ff9c1..36830c9178c2 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Af"</item>
<item msgid="4875147066469902392">"Aan"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Onbeskikbaar"</item>
+ <item msgid="8589336868985358191">"Af"</item>
+ <item msgid="726072717827778234">"Aan"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Onbeskikbaar"</item>
<item msgid="5044688398303285224">"Af"</item>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 1c158b388d74..3e4ca1c25453 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"አዲስ መሣሪያ ለማጣመር ጠቅ ያድርጉ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ቅድመ-ቅምጥን ማዘመን አልተቻለም"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ቅድመ-ቅምጥ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ተመርጧል"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"በዙሪያ ያሉ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ግራ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"መተግበሪያን ሲያጋሩ በዚያ መተግበሪያ ውስጥ የሚታይ ወይም የሚጫወት ማንኛውም ነገር ለ<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ይታያል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ማያ ገፅ አጋራ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ይህን አማራጭ አሰናክሏል"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ለማጋራት መተግበሪያ ይምረጡ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ማያ ገፅዎ cast ይደረግ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"አንድ መተግበሪያ cast ያድርጉ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ለማስወገድ ወደዚህ ይጎትቱ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ቢያንስ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ሰቆች ያስፈልገዎታል"</string>
<string name="qs_edit" msgid="5583565172803472437">"አርትዕ"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ሰዓት"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ሰዓቶችን፣ ደቂቃዎችን፣ ሴኮንዶችን አሳይ"</item>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index 24666e7c12f7..bd240651c07c 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ጠፍቷል"</item>
<item msgid="4875147066469902392">"በርቷል"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"አይገኝም"</item>
+ <item msgid="8589336868985358191">"ጠፍቷል"</item>
+ <item msgid="726072717827778234">"በርቷል"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"አይገኝም"</item>
<item msgid="5044688398303285224">"ጠፍቷል"</item>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index b494f4ec5fad..f9660a340b46 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"انقر لإقران جهاز جديد"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"تعذَّر تعديل الإعداد المسبق"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"الأصوات المحيطة"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"اليسرى"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ستتم مشاركة كل المحتوى المعروض أو المشغَّل على شاشة هذا التطبيق مع تطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\"، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة على الشاشة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"مشاركة الشاشة"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"تم إيقاف هذا الخيار من خلال تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"يُرجى اختيار تطبيق لمشاركة محتواه"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"هل تريد بث محتوى الشاشة؟"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"بث محتوى تطبيق واحد"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"اسحب هنا للإزالة"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"الحدّ الأدنى من عدد المربعات الذي تحتاج إليه هو <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"تعديل"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"الوقت"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"عرض الساعات والدقائق والثواني"</item>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d3ec875711f5..595432e06666 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইচ পেয়াৰ কৰিবলৈ ক্লিক কৰক"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"প্ৰিছেট আপডে’ট কৰিব পৰা নগ’ল"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্ৰিছেট"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বাছনি কৰা হৈছে"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"আশ-পাশ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাওঁফাল"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"আপুনি কোনো এপ্‌ শ্বেয়াৰ কৰি থাকোঁতে সেই এপ্‌টোত দেখুওৱা বা প্লে’ কৰা যিকোনো বস্তু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ত দৃশ্যমান হয়। সেয়ে পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"স্ক্ৰীন শ্বেয়াৰ কৰক"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ এই বিকল্পটো অক্ষম কৰিছে"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"শ্বেয়াৰ কৰিবলৈ এপ্ বাছনি কৰক"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপোনাৰ স্ক্ৰীনখন কাষ্ট কৰিবনে?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"এটা এপ্‌ কাষ্ট কৰক"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"আঁতৰাবৰ বাবে টানি আনি ইয়াত এৰি দিয়ক"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"আপোনাক অতিকমেও <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>খন টাইল লাগিব"</string>
<string name="qs_edit" msgid="5583565172803472437">"সম্পাদনা কৰক"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"সময়"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ঘন্টা, মিনিট আৰু ছেকেণ্ড দেখুৱাওক"</item>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 39bd63e5d27a..d07f11b205cc 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"অফ আছে"</item>
<item msgid="4875147066469902392">"অন কৰা আছে"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"উপলব্ধ নহয়"</item>
+ <item msgid="8589336868985358191">"অফ আছে"</item>
+ <item msgid="726072717827778234">"অন আছে"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"উপলব্ধ নহয়"</item>
<item msgid="5044688398303285224">"অফ আছে"</item>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9655ab75e61b..3cf675d3ab12 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz birləşdirmək üçün klikləyin"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçilib"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ətraf mühit"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Tətbiq paylaşdığınız zaman həmin tətbiqdə göstərilən və ya işə salınan hər şey <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> üçün görünən olacaq. Parol, ödəniş məlumatı, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranı paylaşın"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçimi deaktiv edib"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Paylaşmaq üçün tətbiq seçin"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekran yayımlansın?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Bir tətbiqi yayımlayın"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Silmək üçün bura sürüşdürün"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mozaika lazımdır"</string>
<string name="qs_edit" msgid="5583565172803472437">"Redaktə edin"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Vaxt"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Saat, dəqiqə və saniyəni göstərin"</item>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index a78e67268f82..9fdca5deed05 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Deaktiv"</item>
<item msgid="4875147066469902392">"Aktiv"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Əlçatan deyil"</item>
+ <item msgid="8589336868985358191">"Deaktiv"</item>
+ <item msgid="726072717827778234">"Aktiv"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Əlçatan deyil"</item>
<item msgid="5044688398303285224">"Deaktiv"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f46399659530..b74094e54d36 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unapred određena podešavanja"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izabrano"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada delite aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vidi sav sadržaj koji se prikazuje ili pušta u njoj. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deli ekran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila ovu opciju"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju za deljenje"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite da prebacite ekran?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Prebaci jednu aplikaciju"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovde da biste uklonili"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalan broj pločica je <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Izmeni"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Vreme"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index bbfcf840e53f..5784d4735ede 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nedostupno"</item>
+ <item msgid="8589336868985358191">"Isključeno"</item>
+ <item msgid="726072717827778234">"Uključeno"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 2ece7bd3900e..11c2715fb2ff 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Націсніце, каб спалучыць новую прыладу"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не ўдалося абнавіць набор налад"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор налад"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрана"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Навакольныя гукі"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левы бок"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Калі вы абагульваеце праграму, праграма \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" можа бачыць усё, што паказваецца ці прайграецца ў гэтай праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Абагуліць экран"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" адключыла гэты параметр"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Выберыце праграму для абагульвання"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Уключыць трансляцыю экрана?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Трансліраваць адну праграму"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Перацягніце сюды, каб выдаліць"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Мінімальная колькасць плітак: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Рэдагаваць"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Час"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Паказваць гадзіны, хвіліны і секунды"</item>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index e6b35439ce44..67468b4a983e 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Выключана"</item>
<item msgid="4875147066469902392">"Уключана"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Недаступна"</item>
+ <item msgid="8589336868985358191">"Выключана"</item>
+ <item msgid="726072717827778234">"Уключана"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недаступна"</item>
<item msgid="5044688398303285224">"Выключана"</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 3ab943a658e6..a085b1545867 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за сдвояване на ново устройство"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Предварително зададените настройки не бяха актуализирани"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Предварително зададено"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Околни звуци"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ляво"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Когато споделяте приложение, всичко, което се показва или възпроизвежда в него, е видимо за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Споделяне на екрана"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> деактивира тази опция"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Изберете приложение за споделяне"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Искате ли да предавате екрана си?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Предаване на едно приложение"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Преместете тук с плъзгане за премахване"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Трябва да останат поне <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
<string name="qs_edit" msgid="5583565172803472437">"Редактиране"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Час"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Показване на часовете, минутите и секундите"</item>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index b46d4dffb5fd..535ddcdcc7b6 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Изкл."</item>
<item msgid="4875147066469902392">"Вкл."</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Не е налице"</item>
+ <item msgid="8589336868985358191">"Изкл."</item>
+ <item msgid="726072717827778234">"Вкл."</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Не е налице"</item>
<item msgid="5044688398303285224">"Изкл."</item>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 4ab650edc56d..18d632e95502 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইস পেয়ার করতে ক্লিক করুন"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"প্রিসেট আপডেট করা যায়নি"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্রিসেট"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বেছে নেওয়া হয়েছে"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"সারাউন্ডিং"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাঁদিক"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"কোনও অ্যাপ শেয়ার করার সময়, সেই অ্যাপে দেখা ও চালানো হয় এমন সব কিছু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> দেখতে পাবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"স্ক্রিন শেয়ার করুন"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই বিকল্পটি বন্ধ করে দিয়েছে"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"শেয়ার করার জন্য অ্যাপ বেছে নিন"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপনার স্ক্রিন কাস্ট করতে চান?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"একটি অ্যাপ কাস্ট করুন"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"সরানোর জন্য এখানে টেনে আনুন"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"আপনাকে কমপক্ষে <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>টি টাইল রাখতে হবে"</string>
<string name="qs_edit" msgid="5583565172803472437">"এডিট করুন"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"সময়"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ঘণ্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index afa877ee5c0a..c18af99aafc0 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da uparite novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Zadana postavka"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeli ekran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila tu opciju"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju koju želite dijeliti"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Emitirati ekran?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiraj jednu aplikaciju"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovdje za uklanjanje"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Broj polja mora biti najmanje <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Uredite"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Vrijeme"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index bbfcf840e53f..5784d4735ede 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nedostupno"</item>
+ <item msgid="8589336868985358191">"Isključeno"</item>
+ <item msgid="726072717827778234">"Uključeno"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 3e43c7924678..0404bc70b75e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Valors predefinits"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionat"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Entorn"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerra"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quan comparteixes una aplicació, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pot veure qualsevol cosa que s\'hi mostra o que s\'hi reprodueix. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Comparteix la pantalla"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha desactivat aquesta opció"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Tria una aplicació per compartir"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vols emetre la pantalla?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emet una aplicació"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrossega aquí per suprimir"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Necessites com a mínim <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaics"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edita"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostra les hores, els minuts i els segons"</item>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index 5094d57a0ecf..7afc00f8c149 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Desactivat"</item>
<item msgid="4875147066469902392">"Activat"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"No disponible"</item>
+ <item msgid="8589336868985358191">"Desactivat"</item>
+ <item msgid="726072717827778234">"Activat"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"No disponible"</item>
<item msgid="5044688398303285224">"Desactivat"</item>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index f374913a56cf..e438d6332dd0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybráno"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolí"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vlevo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Při sdílení aplikace vidí <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vše, co se ve sdílené aplikaci nachází nebo děje. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Sdílet obrazovku"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> tuto možnost zakázala"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vyberte aplikaci ke sdílení"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Odeslat obrazovku?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Odeslat jednu aplikaci"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Přetažením sem dlaždice odstraníte"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Potřebujete alespoň tento počet dlaždic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Upravit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Čas"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Zobrazovat hodiny, minuty a sekundy"</item>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 0c7db6763eeb..46ef4ead74f0 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Vypnuto"</item>
<item msgid="4875147066469902392">"Zapnuto"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nedostupné"</item>
+ <item msgid="8589336868985358191">"Vypnuto"</item>
+ <item msgid="726072717827778234">"Zapnuto"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupné"</item>
<item msgid="5044688398303285224">"Vypnuto"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0875aad0986e..52abc4a2fda5 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik for at parre en ny enhed"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forindstilling"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Når du deler en app, er alt, der vises eller afspilles i den pågældende app, synligt for <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Vær derfor forsigtig med f.eks. adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Del skærm"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktiveret denne valgmulighed"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vælg den app, du vil dele fra"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vil du caste din skærm?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast én app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Træk herhen for at fjerne"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Du skal bruge mindst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> felter"</string>
<string name="qs_edit" msgid="5583565172803472437">"Rediger"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Vis timer, minutter og sekunder"</item>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 5558b0b5433f..b4a3eaffda8d 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Fra"</item>
<item msgid="4875147066469902392">"Til"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Ikke tilgængelig"</item>
+ <item msgid="8589336868985358191">"Fra"</item>
+ <item msgid="726072717827778234">"Til"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ikke tilgængelig"</item>
<item msgid="5044688398303285224">"Fra"</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8b783fdcc161..612c52f5c127 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicken, um neues Gerät zu koppeln"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voreinstellung"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ausgewählt"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umgebungsgeräusche"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Wenn du eine App streamst, ist für <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alles sichtbar, was in dieser App angezeigt oder abgespielt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bildschirm teilen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> hat diese Option deaktiviert"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"App zum Teilen auswählen"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Bildschirm streamen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Eine App streamen"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Zum Entfernen hierher ziehen"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Du brauchst mindestens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> Kacheln"</string>
<string name="qs_edit" msgid="5583565172803472437">"Bearbeiten"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Uhrzeit"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Stunden, Minuten und Sekunden anzeigen"</item>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index 2d4d1b6eb3da..ecae8dc4e0dd 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Aus"</item>
<item msgid="4875147066469902392">"An"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nicht verfügbar"</item>
+ <item msgid="8589336868985358191">"Aus"</item>
+ <item msgid="726072717827778234">"An"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nicht verfügbar"</item>
<item msgid="5044688398303285224">"Aus"</item>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c1a9a3a4c19d..2c17a394b022 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Κάντε κλικ για σύζευξη νέας συσκευής"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Δεν ήταν δυνατή η ενημέρωση της προεπιλογής"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Προεπιλογή"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Έχει επιλεγεί"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ήχοι περιβάλλοντος"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Αριστερά"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Όταν μοιράζεστε μια εφαρμογή, οτιδήποτε εμφανίζεται ή αναπαράγεται σε αυτή την εφαρμογή, είναι ορατό στην εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Κοινή χρήση οθόνης"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> απενεργοποίησε αυτή την επιλογή"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Επιλογή εφαρμογής για κοινή χρήση"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Να γίνει μετάδοση της οθόνης σας;"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Μετάδοση μίας εφαρμογής"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Σύρετε εδώ για κατάργηση"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Χρειάζεστε τουλάχιστον <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> πλακίδια"</string>
<string name="qs_edit" msgid="5583565172803472437">"Επεξεργασία"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ώρα"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Να εμφανίζονται ώρες, λεπτά και δευτερόλεπτα"</item>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 76e70719d11f..d8910b3955b9 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Ανενεργό"</item>
<item msgid="4875147066469902392">"Ενεργό"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Μη διαθέσιμο"</item>
+ <item msgid="8589336868985358191">"Ανενεργό"</item>
+ <item msgid="726072717827778234">"Ενεργό"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Μη διαθέσιμο"</item>
<item msgid="5044688398303285224">"Ανενεργός"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 1fee916f670e..7b8f98237c7a 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Time"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 34580ebc9b99..3014e6207e7d 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Unavailable"</item>
+ <item msgid="8589336868985358191">"Off"</item>
+ <item msgid="726072717827778234">"On"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 318f0b43332e..15056c6e9a08 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -419,6 +419,11 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_input_routing_label" msgid="730396728151232306">"Default microphone for calls"</string>
+ <string-array name="hearing_device_input_routing_options">
+ <item msgid="4582190415045337003">"Hearing aid microphone"</item>
+ <item msgid="8501466270452446450">"This phone\'s microphone"</item>
+ </string-array>
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -582,6 +587,7 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you’re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+ <string name="media_projection_entry_app_permission_dialog_single_app_not_supported" msgid="4860247304058870233">"Not supported by the app"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -979,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Time"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Show hours, minutes, and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1fee916f670e..7b8f98237c7a 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Time"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 34580ebc9b99..3014e6207e7d 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Unavailable"</item>
+ <item msgid="8589336868985358191">"Off"</item>
+ <item msgid="726072717827778234">"On"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 1fee916f670e..7b8f98237c7a 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Time"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 34580ebc9b99..3014e6207e7d 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Unavailable"</item>
+ <item msgid="8589336868985358191">"Off"</item>
+ <item msgid="726072717827778234">"On"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Unavailable"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 486b43a2e867..1b15b1b4fe40 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para vincular un dispositivo nuevo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ajuste predeterminado"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sonido envolvente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Cuando compartes una app, todo lo que se muestre o reproduzca en ella será visible en <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> inhabilitó esta opción"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Elige la app para compartir"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"¿Quieres transmitir la pantalla?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir una app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tarjetas"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos y segundos"</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index ecd3fdab13aa..2311b48b6570 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para emparejar un nuevo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preajuste"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Alrededores"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Cuando compartes una aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede ver todo lo que se muestra o reproduce en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha inhabilitado esta opción"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Elige la aplicación que quieres compartir"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"¿Enviar tu pantalla?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Enviar una aplicación"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar una función"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> recuadros"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos y segundos"</item>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 2928c96b9689..9d221715da7e 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Eelseadistus"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valitud"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ümbritsevad helid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasakule"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Rakenduse jagamisel on kogu rakenduses kuvatav või esitatav sisu nähtav rakendusele <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Jaga ekraani"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on selle valiku keelanud"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vali jagamiseks rakendus"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Kas kanda ekraanikuva üle?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Ühe rakenduse ülekandmine"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Lohistage eemaldamiseks siia"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Teil on vaja vähemalt <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> paani"</string>
<string name="qs_edit" msgid="5583565172803472437">"Muutmine"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Kellaaeg"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Kuva tunnid, minutid ja sekundid"</item>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 1defe925cf75..819e9761225c 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Väljas"</item>
<item msgid="4875147066469902392">"Sees"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Pole saadaval"</item>
+ <item msgid="8589336868985358191">"Väljas"</item>
+ <item msgid="726072717827778234">"Sees"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Pole saadaval"</item>
<item msgid="5044688398303285224">"Väljas"</item>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 99dec017c0f4..443632bb543a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Egin klik beste gailu bat parekatzeko"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Aurrezarpena"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Hautatuta"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ingurunea"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ezkerrekoa"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Aplikazio bat partekatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia ikusi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partekatu pantaila"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak aukera desgaitu du"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Aukeratu zein aplikazio partekatu nahi duzun"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Pantaila igorri nahi duzu?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Igorri aplikazio bat"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kentzeko, arrastatu hona"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> lauza behar dituzu gutxienez"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editatu"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ordua"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Erakutsi orduak, minutuak eta segundoak"</item>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index db76009629c4..58f35d1d8511 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"برای جفت کردن دستگاه جدید، کلیک کنید"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"پیش‌تنظیم به‌روزرسانی نشد"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیش‌تنظیم"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"انتخاب‌شده"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"پیرامون"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"چپ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"وقتی برنامه‌ای را هم‌رسانی می‌کنید، هر چیزی که در آن برنامه نمایش داده شود یا پخش شود برای <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> قابل‌مشاهده خواهد بود. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"هم‌رسانی صفحه‌نمایش"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>این گزینه را غیرفعال کرده است"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"برنامه‌ای را برای هم‌رسانی انتخاب کنید"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"محتوای صفحه‌نمایش شما پخش شود؟"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"پخش کردن محتوای یک برنامه"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"برای حذف، به اینجا بکشید"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"حداقل به <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> کاشی نیاز دارید"</string>
<string name="qs_edit" msgid="5583565172803472437">"ویرایش"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"زمان"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ساعت، دقیقه و ثانیه نشان داده شود"</item>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index ee9429402779..68ca663eadc1 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"خاموش"</item>
<item msgid="4875147066469902392">"روشن"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"دردسترس نیست"</item>
+ <item msgid="8589336868985358191">"خاموش"</item>
+ <item msgid="726072717827778234">"روشن"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"دردسترس نیست"</item>
<item msgid="5044688398303285224">"خاموش"</item>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 8df9aeb04f92..1b767db0ca57 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -421,6 +421,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Esiasetus"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valittu"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ympäristö"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasen"</string>
@@ -584,6 +588,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kun jaat sovelluksen, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> näkee kaiken sovelluksessa näkyvän tai toistetun sisällön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Jaa näyttö"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on poistanut vaihtoehdon käytöstä"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Valitse jaettava sovellus"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Striimataanko näyttö?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Striimaa yksi sovellus"</string>
@@ -982,6 +988,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Poista vetämällä tähän."</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kiekkoa on vähimmäismäärä"</string>
<string name="qs_edit" msgid="5583565172803472437">"Muokkaa"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Aika"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Näytä tunnit, minuutit ja sekunnit"</item>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 76a77ad058ef..12487bd4b818 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Poissa päältä"</item>
<item msgid="4875147066469902392">"Päällä"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Ei saatavilla"</item>
+ <item msgid="8589336868985358191">"Pois päältä"</item>
+ <item msgid="726072717827778234">"Päällä"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ei saatavilla"</item>
<item msgid="5044688398303285224">"Poissa päältä"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 9bd16d975d74..2a315e453cae 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquez ici pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Environnement"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Lorsque vous partagez une appli, tout ce qui s\'y affiche ou s\'y joue est visible par <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partager l\'écran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choisir l\'appli à partager"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Diffuser votre écran?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Diffuser une appli"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les tuiles ici pour les retirer"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Vous avez besoin d\'au moins <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles"</string>
<string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Afficher les heures, les minutes et les secondes"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 01f33917a979..6b94691d729f 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Désactivée"</item>
<item msgid="4875147066469902392">"Activé"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Non accessible"</item>
+ <item msgid="8589336868985358191">"Désactivé"</item>
+ <item msgid="726072717827778234">"Activé"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non disponible"</item>
<item msgid="5044688398303285224">"Désactivée"</item>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 63ac0cab4b17..d7e9d446bec1 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sons environnants"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Lorsque vous partagez une appli, tout ce qui est affiché ou lu dans celle-ci est visible par <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partager l\'écran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choisir l\'appli à partager"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Caster votre écran ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Caster une appli"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les blocs ici pour les supprimer"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Au minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles sont nécessaires"</string>
<string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Afficher les heures, les minutes et les secondes"</item>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 620e46c88cd5..ea91d2f7e016 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Désactivé"</item>
<item msgid="4875147066469902392">"Activé"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Indisponible"</item>
+ <item msgid="8589336868985358191">"Désactivé"</item>
+ <item msgid="726072717827778234">"Activé"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponible"</item>
<item msgid="5044688398303285224">"Désactivé"</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 80da559ba1c5..f4a4ceb526dc 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic para vincular un novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Configuración predeterminada"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Elemento seleccionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerdo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Se compartes toda a pantalla, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> poderá ver todo o contido que apareza ou se reproduza nesa aplicación. Ten coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> desactivou esta opción"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escoller unha aplicación para compartir"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Queres emitir a túa pantalla?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitir unha aplicación"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra o elemento ata aquí para quitalo"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Como mínimo ten que haber <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaicos"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index ca19e0ecd24d..9b05a8705adc 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Non"</item>
<item msgid="4875147066469902392">"Si"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Non dispoñible"</item>
+ <item msgid="8589336868985358191">"Desactivado"</item>
+ <item msgid="726072717827778234">"Activado"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non dispoñible"</item>
<item msgid="5044688398303285224">"Non"</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 17bcdf091f9e..2a8fe315647e 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -252,10 +252,8 @@
<string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> થી કનેક્ટ થયાં."</string>
<string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> થી કનેક્ટ કરેલ."</string>
<string name="accessibility_expand_group" msgid="521237935987978624">"ગ્રૂપને મોટું કરો."</string>
- <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
- <skip />
- <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
- <skip />
+ <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ડિવાઇસને ગ્રૂપમાં ઉમેરો."</string>
+ <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ડિવાઇસને ગ્રૂપમાંથી કાઢી નાખો."</string>
<string name="accessibility_open_application" msgid="1749126077501259712">"ઍપ્લિકેશન ખોલો."</string>
<string name="accessibility_not_connected" msgid="4061305616351042142">"કનેક્ટ થયેલું નથી."</string>
<string name="data_connection_roaming" msgid="375650836665414797">"રોમિંગ"</string>
@@ -333,8 +331,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ઇનપુટ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"સાંભળવામાં મદદ આપતા યંત્રો"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ચાલુ કરી રહ્યાં છીએ…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"બ્રાઇટનેસ ગોઠવી શકાતી નથી કારણ કે તે લોકપ્રિય ઍપ દ્વારા નિયંત્રિત કરવામાં આવી રહી છે"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"લોકેશન"</string>
@@ -422,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"નવા ડિવાઇસ સાથે જોડાણ કરવા માટે ક્લિક કરો"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"પ્રીસેટ અપડેટ કરી શક્યા નથી"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"પ્રીસેટ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"પસંદ કરી છે"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"આસપાસના અવાજો"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ડાબે"</string>
@@ -585,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"જ્યારે તમે કોઈ ઍપને શેર કરી રહ્યાં હો, ત્યારે તે ઍપ પર બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ને દેખાય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"સ્ક્રીન શેર કરો"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> દ્વારા આ વિકલ્પ બંધ કરવામાં આવ્યો છે"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"શેર કરવા માટે ઍપ પસંદ કરો"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"તમારી સ્ક્રીનને કાસ્ટ કરીએ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"એક ઍપને કાસ્ટ કરો"</string>
@@ -983,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"દૂર કરવા માટે અહીં ખેંચો"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"તમને ઓછામાં ઓછી <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ટાઇલની જરૂર છે"</string>
<string name="qs_edit" msgid="5583565172803472437">"ફેરફાર કરો"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"સમય"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"કલાક, મિનિટ અને સેકન્ડ બતાવો"</item>
@@ -1344,7 +1349,7 @@
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ટાઇલ ઉમેરો"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ટાઇલ ઉમેરશો નહીં"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"વપરાશકર્તા પસંદ કરો"</string>
- <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ઍપ સક્રિય છે}one{# ઍપ સક્રિય છે}other{# ઍપ સક્રિય છે}}"</string>
+ <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ઍપ ઍક્ટિવ છે}one{# ઍપ ઍક્ટિવ છે}other{# ઍપ ઍક્ટિવ છે}}"</string>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</string>
<string name="fgs_manager_dialog_message" msgid="2670045017200730076">"જ્યારે તમે આ ઍપનો ઉપયોગ ન કરતા હો, ત્યારે પણ તે સક્રિય અને ચાલતી હોય છે. આનાથી તેની કાર્યક્ષમતામાં સુધારો થાય છે, પરંતુ બૅટરીની આવરદાને અસર પણ થઈ શકે છે."</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index 759e43664379..c3fb94129883 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"બંધ છે"</item>
<item msgid="4875147066469902392">"ચાલુ છે"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"અનુપલબ્ધ"</item>
+ <item msgid="8589336868985358191">"બંધ"</item>
+ <item msgid="726072717827778234">"ચાલુ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ઉપલબ્ધ નથી"</item>
<item msgid="5044688398303285224">"બંધ છે"</item>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f4c05ba2f8c5..922794daa24b 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चुना गया"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"आस-पास का वॉल्यूम"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बाईं ओर के वॉल्यूम के लिए"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"जब कोई ऐप्लिकेशन शेयर किया जाता है, तो उस ऐप्लिकेशन में दिख रहा या चलाया जा रहा पूरा कॉन्टेंट <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> पर दिखता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रीन शेयर करें"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ने इस विकल्प को बंद कर दिया है"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"शेयर करने के लिए ऐप्लिकेशन चुनें"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"क्या स्क्रीन को कास्ट करना है?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एक ऐप्लिकेशन को कास्ट करें"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"हटाने के लिए यहां खींचें और छोड़ें"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"आपके पास कम से कम <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलें होनी चाहिए"</string>
<string name="qs_edit" msgid="5583565172803472437">"बदलाव करें"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"समय"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"घंटे, मिनट और सेकंड दिखाएं"</item>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index 410f25db0900..d331e3a8a5db 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"बंद है"</item>
<item msgid="4875147066469902392">"चालू है"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"उपलब्ध नहीं है"</item>
+ <item msgid="8589336868985358191">"बंद है"</item>
+ <item msgid="726072717827778234">"चालू है"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध नहीं है"</item>
<item msgid="5044688398303285224">"बंद है"</item>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9d2509404a8c..3213d59dadf9 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unaprijed definirana postavka"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji bit će vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeljenje zaslona"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućila je ovu opciju"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju za dijeljenje"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite li emitirati zaslon?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiranje jedne aplikacije"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Povucite ovdje za uklanjanje"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Potrebno je barem <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pločica"</string>
<string name="qs_edit" msgid="5583565172803472437">"Uređivanje"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Vrijeme"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index bbfcf840e53f..5784d4735ede 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Isključeno"</item>
<item msgid="4875147066469902392">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nedostupno"</item>
+ <item msgid="8589336868985358191">"Isključeno"</item>
+ <item msgid="726072717827778234">"Uključeno"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupno"</item>
<item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index bdeececfd9ae..4327594260fc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Beállításkészlet"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Kiválasztva"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Környezet"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Bal"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Alkalmazás megosztása közben az adott appban megjelenített vagy lejátszott minden tartalom látható a(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> számára. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Képernyő megosztása"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> letiltotta ezt a beállítást"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Válassza ki a megosztani kívánt alkalmazást"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Átküldi a képernyőt?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Egyetlen app átküldése"</string>
@@ -794,8 +800,7 @@
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Be: Arcalapú"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Kész"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Alkalmaz"</string>
- <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
- <skip />
+ <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Kikapcsolás"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Néma"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"Alapértelmezett"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string>
@@ -980,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Húzza ide az eltávolításhoz"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Legalább <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kártya szükséges"</string>
<string name="qs_edit" msgid="5583565172803472437">"Szerkesztés"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Idő"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Óra, perc és másodperc megjelenítése"</item>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 8bd57214a28d..168cd0686e2d 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Ki"</item>
<item msgid="4875147066469902392">"Be"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nem áll rendelkezésre"</item>
+ <item msgid="8589336868985358191">"Ki"</item>
+ <item msgid="726072717827778234">"Be"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nem áll rendelkezésre"</item>
<item msgid="5044688398303285224">"Ki"</item>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index d448486faf64..eaff82423bd8 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Սեղմեք՝ նոր սարք զուգակցելու համար"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Չհաջողվեց թարմացնել կարգավորումների հավաքածուն"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Կարգավորումների հավաքածու"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ընտրված է"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Շրջակայք"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ձախ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Երբ դուք որևէ հավելված եք հեռարձակում, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին տեսանելի կլինի այն ամենը, ինչ ցուցադրվում կամ նվագարկվում է այդ հավելվածում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ցուցադրել էկրանը"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ն անջատել է այս ընտրանքը"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Հավելվածի ընտրություն՝ կիսվելու համար"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Հեռարձակե՞լ ձեր էկրանը"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Հեռարձակել մեկ հավելված"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Քաշեք այստեղ՝ հեռացնելու համար"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Հարկավոր է առնվազն <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> սալիկ"</string>
<string name="qs_edit" msgid="5583565172803472437">"Փոփոխել"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ժամ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Ցույց տալ ժամերը, րոպեները և վայրկյանները"</item>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index 3497c404600b..c1b2d71aed3b 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Անջատված է"</item>
<item msgid="4875147066469902392">"Միացված է"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Հասանելի չէ"</item>
+ <item msgid="8589336868985358191">"Անջատված է"</item>
+ <item msgid="726072717827778234">"Միացված է"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Հասանելի չէ"</item>
<item msgid="5044688398303285224">"Անջատված է"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 5867bf7c5cc6..763f76754b74 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Suara sekitar"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Jika Anda membagikan aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan terlihat oleh <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bagikan layar"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah menonaktifkan opsi ini"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pilih aplikasi yang akan dibagikan"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmisikan layar?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmisikan satu aplikasi"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Tarik ke sini untuk menghapus"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Anda membutuhkan setidaknya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kartu"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Waktu"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Tampilkan jam, menit, dan detik"</item>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 7df0b0d9f34c..a00d87d8bfd7 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Nonaktif"</item>
<item msgid="4875147066469902392">"Aktif"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Tidak tersedia"</item>
+ <item msgid="8589336868985358191">"Nonaktif"</item>
+ <item msgid="726072717827778234">"Aktif"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Tidak tersedia"</item>
<item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index f949400bf09d..970a9130135a 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forstilling"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valið"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umhverfi"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vinstri"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deila skjá"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> slökkti á þessum valkosti"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velja forrit til að deila"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Varpa skjánum?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Varpa einu forriti"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Dragðu hingað til að fjarlægja"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Flísarnar mega ekki vera færri en <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Breyta"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tími"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Sýna klukkustundir, mínútur og sekúndur"</item>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index d1b04e05ad7f..7790b11b5fa4 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Slökkt"</item>
<item msgid="4875147066469902392">"Kveikt"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Ekki í boði"</item>
+ <item msgid="8589336868985358191">"Slökkt"</item>
+ <item msgid="726072717827778234">"Kveikt"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ekki í boði"</item>
<item msgid="5044688398303285224">"Slökkt"</item>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 708fa78bedff..7323037cb00b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic per accoppiare un nuovo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selezionato"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Audio ambientale"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sinistra"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando condividi un\'app, tutto ciò che viene mostrato o riprodotto al suo interno è visibile a <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Condividi schermo"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha disattivato questa opzione"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Scegli l\'app da condividere"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Trasmettere lo schermo?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Trasmetti un\'app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Trascina qui per rimuovere"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Occorrono almeno <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> schede"</string>
<string name="qs_edit" msgid="5583565172803472437">"Modifica"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostra ore, minuti e secondi"</item>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index afbd3d9b1910..2d3f55361307 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Off"</item>
<item msgid="4875147066469902392">"On"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Non disponibile"</item>
+ <item msgid="8589336868985358191">"Off"</item>
+ <item msgid="726072717827778234">"On"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Non disponibile"</item>
<item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 35500fbc4107..3ee24a3d5a75 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"צריך ללחוץ כדי להתאים מכשיר חדש"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"לא ניתן לעדכן את ההגדרה הקבועה מראש"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"הגדרה קבועה מראש"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"נבחר"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"הרעשים בסביבה"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"שמאל"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"כשמשתפים אפליקציה, כל מה שרואים או מפעילים בה מופיע גם ב-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. מומלץ להיזהר ולא לחשוף פרטים אישיים כמו סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"שיתוף המסך"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> השביתה את האפשרות הזו"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"בחירת אפליקציה לשיתוף"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"‏להפעיל Cast של המסך?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"‏הפעלת Cast של אפליקציה אחת"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"אפשר לגרור לכאן כדי להסיר"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"יש צורך ב-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> אריחים לפחות"</string>
<string name="qs_edit" msgid="5583565172803472437">"עריכה"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"שעה"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"הצגת שעות, דקות ושניות"</item>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index fc792b6f9850..1e85479ca0eb 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"クリックすると、新しいデバイスをペア設定できます"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"プリセットを更新できませんでした"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"プリセット"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"選択中"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"周囲の音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"アプリを共有すると、そのアプリで表示または再生される内容が <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> にすべて公開されます。パスワード、お支払い情報、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"画面を共有"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> がこのオプションを無効にしています"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"共有するアプリを選択"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"画面をキャストしますか?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"1 つのアプリをキャスト"</string>
@@ -794,8 +800,7 @@
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ON - 顔ベース"</string>
<string name="inline_done_button" msgid="6043094985588909584">"完了"</string>
<string name="inline_ok_button" msgid="603075490581280343">"適用"</string>
- <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
- <skip />
+ <string name="inline_turn_off_notifications" msgid="2653064779176881329">"OFF にする"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
@@ -980,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"削除するにはここにドラッグ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"タイルは <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個以上必要です"</string>
<string name="qs_edit" msgid="5583565172803472437">"編集"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"時間"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"時間、分、秒を表示"</item>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 4827ad38dfa7..4a6b210797f9 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"OFF"</item>
<item msgid="4875147066469902392">"ON"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"使用不可"</item>
+ <item msgid="8589336868985358191">"OFF"</item>
+ <item msgid="726072717827778234">"ON"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"使用不可"</item>
<item msgid="5044688398303285224">"OFF"</item>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index e13a1b3a3bd8..0a25f83d1185 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"დააწკაპუნეთ ახალი მოწყობილობის დასაწყვილებლად"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"წინასწარ დაყენებული პარამეტრების განახლება ვერ მოხერხდა"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"წინასწარ დაყენებული"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"არჩეულია"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"გარემოცვა"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"მარცხენა"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"აპის გაზიარებისას <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ხედავს ყველაფერს, რაც ჩანს ან უკრავს ამ აპში. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ეკრანის გაზიარება"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-მა გათიშა ეს ვარიანტი"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"გაზიარებისთვის აპის არჩევა"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"გსურთ თქვენი ეკრანის ტრანსლირება?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ერთი აპის ტრანსლირება"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ამოსაშლელად, ჩავლებით გადმოიტანეთ აქ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"თქვენ გჭირდებათ მოზაიკის <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ფილა მაინც"</string>
<string name="qs_edit" msgid="5583565172803472437">"რედაქტირება"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"დრო"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"საათების, წუთებისა და წამების ჩვენება"</item>
@@ -1249,7 +1257,7 @@
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ხელმისაწვდომი მოწყობილობები გამომავალი აუდიოსთვის."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ხმა"</string>
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
- <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და დისპლეები"</string>
+ <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და ეკრანები"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"შემოთავაზებული მოწყობილობები"</string>
<string name="media_input_group_title" msgid="2057057473860783021">"შემავალი"</string>
<string name="media_output_group_title" msgid="6789001895863332576">"გამომავალი"</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index ebf28c89587b..6440b5f74a94 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"გამორთულია"</item>
<item msgid="4875147066469902392">"ჩართულია"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"მიუწვდომელი"</item>
+ <item msgid="8589336868985358191">"გამორთული"</item>
+ <item msgid="726072717827778234">"ჩართული"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"მიუწვდომელია"</item>
<item msgid="5044688398303285224">"გამორთულია"</item>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 5fc8b47869b7..c7e8d81f4e45 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңа құрылғыны жұптау үшін басыңыз."</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Параметрлер жинағын жаңарту мүмкін болмады."</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Параметрлер жинағы"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Таңдалды"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айнала"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол жақ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Қолданбаны бөліскен кезде, онда көрінетін не ойнатылатын барлық контент <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> қолданбасында көрсетіледі. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды, фотосуреттерді және аудио мен бейнені ашқанда сақ болыңыз."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлісу"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы осы опцияны өшірді."</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлісетін қолданба экранын таңдау"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Экранды трансляциялау керек пе?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Бір қолданба экранын трансляциялау"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Керексіздерін осы жерге сүйреңіз"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Кемінде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> бөлшек қажет."</string>
<string name="qs_edit" msgid="5583565172803472437">"Өзгерту"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Уақыт"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Сағаттарды, минуттарды және секундтарды көрсету"</item>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 45316aa1391e..a177ca2862da 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Өшірулі"</item>
<item msgid="4875147066469902392">"Қосулы"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Қолжетімді емес"</item>
+ <item msgid="8589336868985358191">"Өшірулі"</item>
+ <item msgid="726072717827778234">"Қосулы"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Қолжетімсіз"</item>
<item msgid="5044688398303285224">"Өшірулі"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 579c509dd6db..349e34a2c8cd 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ចុច ដើម្បីផ្គូផ្គងឧបករណ៍ថ្មី"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"មិនអាច​ប្ដូរ​ការកំណត់ជាមុន​បានទេ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"កំណត់ជាមុន"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"បានជ្រើសរើស"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"មជ្ឈដ្ឋានជុំវិញ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ឆ្វេង"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"នៅពេលអ្នកបង្ហាញកម្មវិធីណាមួយ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មើលឃើញអ្វីគ្រប់យ៉ាងដែលបង្ហាញ ឬចាក់ក្នុងកម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"បង្ហាញ​អេក្រង់"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> បានបិទជម្រើសនេះ"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ជ្រើសរើស​កម្មវិធី​ដើម្បី​ចែករំលែក"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"បញ្ជូនអេក្រង់របស់អ្នកឬ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"បញ្ជូនកម្មវិធីមួយ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"អូសទីនេះដើម្បីយកចេញ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"អ្នក​ត្រូវការ​ប្រអប់​យ៉ាងតិច <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"កែ"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ម៉ោង"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"បង្ហាញម៉ោង នាទី និងវិនាទី"</item>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index ec120089a220..49c549f6016a 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"បិទ"</item>
<item msgid="4875147066469902392">"បើក"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"មិនមានទេ"</item>
+ <item msgid="8589336868985358191">"បិទ"</item>
+ <item msgid="726072717827778234">"បើក"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"មិនមានទេ"</item>
<item msgid="5044688398303285224">"បិទ"</item>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index c84b33baed10..0fa4c2476151 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ಪ್ರಿಸೆಟ್‌"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ಆ್ಯಂಬಿಯೆಂಟ್ ವಾಲ್ಯೂಮ್"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ಎಡ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿದ ಏನಾದರೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಗೆ ಗೋಚರಿಸುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ಸ್ಕ್ರೀನ್‌ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ಹಂಚಿಕೊಳ್ಳಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಿತ್ತರಿಸಬೇಕೇ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಬಿತ್ತರಿಸಿ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ತೆಗೆದುಹಾಕಲು ಇಲ್ಲಿ ಡ್ರ್ಯಾಗ್‌ ಮಾಡಿ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ನಿಮಗೆ ಕನಿಷ್ಠ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ಟೈಲ್‌ಗಳ ಅಗತ್ಯವಿದೆ"</string>
<string name="qs_edit" msgid="5583565172803472437">"ಎಡಿಟ್"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ಸಮಯ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ಗಂಟೆಗಳು, ನಿಮಿಷಗಳು, ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು"</item>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index ad57922c9f2c..712936a39299 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ಆಫ್"</item>
<item msgid="4875147066469902392">"ಆನ್"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"ಲಭ್ಯವಿಲ್ಲ"</item>
+ <item msgid="8589336868985358191">"ಆಫ್ ಆಗಿದೆ"</item>
+ <item msgid="726072717827778234">"ಆನ್ ಆಗಿದೆ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ಲಭ್ಯವಿಲ್ಲ"</item>
<item msgid="5044688398303285224">"ಆಫ್"</item>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 048050cf53df..2b9fc89af8b4 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"새 기기와 페어링하려면 클릭하세요"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"사전 설정을 업데이트할 수 없음"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"미리 설정"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"선택됨"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"주변 소리"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"왼쪽"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"앱을 공유하면 앱에 표시되거나 앱에서 재생되는 모든 항목이 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에 표시됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"화면 공유"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 이 옵션을 사용 중지했습니다."</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"공유할 앱 선택"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"화면을 전송하시겠습니까?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"앱 1개 전송"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"여기로 드래그하여 삭제"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>개 이상의 타일이 필요합니다."</string>
<string name="qs_edit" msgid="5583565172803472437">"수정"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"시간"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"시간, 분, 초 표시"</item>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 49113eea79b7..f31f8106d374 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"꺼짐"</item>
<item msgid="4875147066469902392">"켜짐"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"사용할 수 없음"</item>
+ <item msgid="8589336868985358191">"사용 안함"</item>
+ <item msgid="726072717827778234">"사용"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"이용 불가"</item>
<item msgid="5044688398303285224">"꺼짐"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index e6b108126012..b1f6f484ed59 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңы түзмөк кошуу үчүн басыңыз"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Алдын ала коюлган параметрлер жаңыртылган жок"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Алдын ала коюлган параметрлер"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Тандалды"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айланадагы үндөр"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө, андагы нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видеолор менен этият болуңуз."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлүшүү"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлүшүү үчүн колдонмо тандоо"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Экранды башка түзмөккө чыгарасызбы?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Бир колдонмону чыгаруу"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Өчүрүү үчүн бул жерге сүйрөңүз"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Сизге жок дегенде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> мозаика керек"</string>
<string name="qs_edit" msgid="5583565172803472437">"Түзөтүү"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Убакыт"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Сааттар, мүнөттөр жана секунддар"</item>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 68f8987a02dc..fe451facb749 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Өчүк"</item>
<item msgid="4875147066469902392">"Күйүк"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Жеткиликсиз"</item>
+ <item msgid="8589336868985358191">"Өчүк"</item>
+ <item msgid="726072717827778234">"Күйүк"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Жеткиликсиз"</item>
<item msgid="5044688398303285224">"Өчүк"</item>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index e7229e8f3704..c2a4e8fad79b 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ຄລິກເພື່ອຈັບຄູ່ອຸປະກອນໃໝ່"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ບໍ່ສາມາດອັບເດດການຕັ້ງຄ່າລ່ວງໜ້າໄດ້"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ຄ່າທີ່ກຳນົດລ່ວງໜ້າ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ເລືອກແລ້ວ"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ສຽງແວດລ້ອມ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ຊ້າຍ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ເມື່ອທ່ານແບ່ງປັນແອັບຂອງທ່ານ, ຄົນອື່ນຈະເບິ່ງເຫັນທຸກຢ່າງທີ່ສະແດງ ຫຼື ຫຼິ້ນໃນແອັບໃນ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ແບ່ງປັນໜ້າຈໍ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ປິດການນຳໃຊ້ຕົວເລືອກນີ້ແລ້ວ"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ເລືອກແອັບທີ່ຈະແບ່ງປັນ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ສົ່ງສັນຍານໜ້າຈໍຂອງທ່ານບໍ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ສົ່ງສັນຍານແອັບ 1 ລາຍການ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ລາກມາບ່ອນນີ້ເພື່ອລຶບອອກ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ທ່ານຍຕ້ອງໃຊ້ຢ່າງໜ້ອຍ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ຊ່ອງ"</string>
<string name="qs_edit" msgid="5583565172803472437">"ແກ້ໄຂ"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ເວລາ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ສະແດງຊົ່ວໂມງ, ນາທີ ແລະ ວິນາທີ"</item>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 90390e23162b..72c57e645879 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ປິດ"</item>
<item msgid="4875147066469902392">"ເປີດ"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</item>
+ <item msgid="8589336868985358191">"ປິດ"</item>
+ <item msgid="726072717827778234">"ເປີດ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
<item msgid="5044688398303285224">"ປິດ"</item>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6563cb97f35d..48ab51b46e57 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Spustelėkite, kad susietumėte naują įrenginį"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Išankstiniai nustatymai"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Pasirinkta"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Aplinka"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kairė"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kai bendrinate programą, „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ matomas visas toje programoje rodomas ar leidžiamas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bendrinti ekraną"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Programoje „<xliff:g id="APP_NAME">%1$s</xliff:g>“ ši parinktis išjungta"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Norimos bendrinti programos pasirinkimas"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Perduoti ekraną?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Perduoti vieną programą"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Vilkite čia, jei norite pašalinti"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Turi būti bent <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> išklotinės elem."</string>
<string name="qs_edit" msgid="5583565172803472437">"Redaguoti"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Laikas"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Rodyti valandas, minutes ir sekundes"</item>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 3e1f3c702e61..4ed6bd95303a 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Išjungta"</item>
<item msgid="4875147066469902392">"Įjungta"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nepasiekiama"</item>
+ <item msgid="8589336868985358191">"Išjungta"</item>
+ <item msgid="726072717827778234">"Įjungta"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nepasiekiama"</item>
<item msgid="5044688398303285224">"Išjungta"</item>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0c030b7029f9..e5c407f30b6c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pirmsiestatījums"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Atlasīts"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Apkārtnes skaņas"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Pa kreisi"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kopīgojot lietotni, lietotnei <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ir pieejams viss kopīgotajā lietotnē parādītais vai atskaņotais saturs. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Kopīgot ekrānu"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> tika atspējota šī opcija"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Lietotnes izvēlēšanās kopīgošanai"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vai apraidīt ekrānu?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Apraidīt vienu lietotni"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Lai noņemtu vienumus, velciet tos šeit."</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Nepieciešami vismaz <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> elementi"</string>
<string name="qs_edit" msgid="5583565172803472437">"Rediģēt"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Laiks"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Rādīt stundas, minūtes un sekundes"</item>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index e55babc7317b..0c59186e2165 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Izslēgts"</item>
<item msgid="4875147066469902392">"Ieslēgts"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nav pieejams"</item>
+ <item msgid="8589336868985358191">"Izslēgts"</item>
+ <item msgid="726072717827778234">"Ieslēgts"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nav pieejams"</item>
<item msgid="5044688398303285224">"Izslēgts"</item>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index b798f457ee8b..e546fb584ed3 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Опкружување"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Додека споделувате апликација, сѐ што се прикажува или пушта на таа апликација е видливо за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Сподели екран"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ја оневозможи опцијава"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Изберете апликација за споделување"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Да се емитува вашиот екран?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Емитувајте една апликација"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Повлечете тука за да се отстрани"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Потребни ви се најмалку <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
<string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Време"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Прикажи часови, минути и секунди"</item>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 8986ca5a7c86..0f32b8e88573 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Исклучено"</item>
<item msgid="4875147066469902392">"Вклучено"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Недостапно"</item>
+ <item msgid="8589336868985358191">"Исклучено"</item>
+ <item msgid="726072717827778234">"Вклучено"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недостапно"</item>
<item msgid="5044688398303285224">"Исклучено"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index eb7da33b02d2..17b1c3d9d49c 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"പുതിയ ഉപകരണം ജോടിയാക്കാൻ ക്ലിക്ക് ചെയ്യുക"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"പ്രീസെറ്റ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"പ്രീസെറ്റ്"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"തിരഞ്ഞെടുത്തു"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"സറൗണ്ടിംഗ്‌സ്"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ഇടത്"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"നിങ്ങളുടെ ആപ്പ് പങ്കിടുമ്പോൾ, ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാ കാര്യങ്ങളും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ദൃശ്യമാകും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങളിൽ ശ്രദ്ധ പുലർത്തുക."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"സ്‌ക്രീൻ പങ്കിടുക"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഈ ഓപ്‌ഷൻ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"പങ്കിടാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"നിങ്ങളുടെ സ്ക്രീൻ കാസ്റ്റ് ചെയ്യണോ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ഒരു ആപ്പ് കാസ്റ്റ് ചെയ്യുക"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"നീക്കംചെയ്യുന്നതിന് ഇവിടെ വലിച്ചിടുക"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"നിങ്ങൾക്ക് ചുരുങ്ങിയത് <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ടൈലുകളെങ്കിലും വേണം"</string>
<string name="qs_edit" msgid="5583565172803472437">"എഡിറ്റ് ചെയ്യുക"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"സമയം"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"മണിക്കൂറും മിനിറ്റും സെക്കൻഡും കാണിക്കുക"</item>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index a7098c9ef814..c6ba7f16fa22 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ഓഫാണ്"</item>
<item msgid="4875147066469902392">"ഓണാണ്"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"ലഭ്യമല്ല"</item>
+ <item msgid="8589336868985358191">"ഓഫാണ്"</item>
+ <item msgid="726072717827778234">"ഓണാണ്"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ലഭ്യമല്ല"</item>
<item msgid="5044688398303285224">"ഓഫാണ്"</item>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 3adddc2d27ad..ba7baf4ae5b0 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Шинэ төхөөрөмж хослуулахын тулд товшино уу"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Урьдчилсан тохируулгыг шинэчилж чадсангүй"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Урьдчилсан тохируулга"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Сонгосон"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Орчин тойрон"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Зүүн"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Таныг апп хуваалцаж байхад тухайн аппад харуулж эсвэл тоглуулж буй аливаа зүйл <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-д харагдана. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Дэлгэцийг хуваалцах"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> энэ сонголтыг идэвхгүй болгосон"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Хуваалцах апп сонгох"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Дэлгэцээ дамжуулах уу?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Нэг апп дамжуулах"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Устгахын тулд энд зөөнө үү"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Танд хамгийн багадаа <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> хавтан шаардлагатай"</string>
<string name="qs_edit" msgid="5583565172803472437">"Засах"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Цаг"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Цаг, минут, секундийг харуулах"</item>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 9b5a6e3c3037..394c42e5f3a7 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Унтраалттай"</item>
<item msgid="4875147066469902392">"Асаалттай"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Боломжгүй"</item>
+ <item msgid="8589336868985358191">"Унтраалттай"</item>
+ <item msgid="726072717827778234">"Асаалттай"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Боломжгүй"</item>
<item msgid="5044688398303285224">"Унтраалттай"</item>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 08ef7b2e9cfc..d6d8e1cfa70d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नवीन डिव्हाइस पेअर करण्यासाठी क्लिक करा"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट करता आले नाही"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"निवडला आहे"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"जवळपासचे"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"डावे"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"तुम्ही अ‍ॅप शेअर करता, तेव्हा त्या अ‍ॅपमध्ये दाखवल्या किंवा प्ले होणाऱ्या कोणत्याही गोष्टी <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> साठी दृश्यमान असतात. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रीन शेअर करा"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा पर्याय बंद केला आहे"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"शेअर करण्यासाठी अ‍ॅप निवडा"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"तुमची स्क्रीन कास्ट करायची आहे का?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एक अ‍ॅप कास्ट करा"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"काढण्यासाठी येथे ड्रॅग करा"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"तुम्हाला किमान <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलची गरज आहे"</string>
<string name="qs_edit" msgid="5583565172803472437">"संपादित करा"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"वेळ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"तास, मिनिटे आणि सेकंद दर्शवा"</item>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index a5930d9ff295..4809c740406a 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"बंद आहे"</item>
<item msgid="4875147066469902392">"सुरू आहे"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"उपलब्ध नाही"</item>
+ <item msgid="8589336868985358191">"बंद आहे"</item>
+ <item msgid="726072717827778234">"सुरू आहे"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध नाही"</item>
<item msgid="5044688398303285224">"बंद आहे"</item>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 5aec75608f76..2aa5068557d6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menggandingkan peranti baharu"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pratetapan"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Persekitaran"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Apabila anda berkongsi apl, apa-apa sahaja kandungan yang dipaparkan atau dimainkan dalam apl tersebut boleh dilihat oleh <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Kongsi skrin"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah melumpuhkan pilihan ini"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pilih apl untuk dikongsi"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Hantar skrin anda?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Hantar satu apl"</string>
@@ -794,8 +800,7 @@
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Hidup - Berasaskan wajah"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Selesai"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Guna"</string>
- <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
- <skip />
+ <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Matikan"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"Lalai"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automatik"</string>
@@ -980,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Seret ke sini untuk mengalih keluar"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Anda memerlukan sekurang-kurangnya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> jubin"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Masa"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Tunjukkan jam, minit dan saat"</item>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index eca55a34e028..88544435c076 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Mati"</item>
<item msgid="4875147066469902392">"Hidup"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Tidak tersedia"</item>
+ <item msgid="8589336868985358191">"Mati"</item>
+ <item msgid="726072717827778234">"Hidup"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Tidak tersedia"</item>
<item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 98f937b377e1..70f8259df0a7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"စက်အသစ် တွဲချိတ်ရန် နှိပ်ပါ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"အသင့်သုံးကို အပ်ဒိတ်လုပ်၍မရပါ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ကြိုတင်သတ်မှတ်ချက်"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ရွေးထားသည်"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ဝန်းကျင်အသံ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ဘယ်"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"အက်ပ်ကို မျှဝေနေချိန်တွင် ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က မြင်နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"စခရင် မျှဝေရန်"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ဤရွေးစရာကို ပိတ်ထားသည်"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"မျှဝေရန် အက်ပ်ရွေးခြင်း"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"သင့်ဖန်သားပြင်ကို ကာစ်လုပ်မလား။"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"အက်ပ်တစ်ခုကို ကာစ်လုပ်ရန်"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ဖယ်ရှားရန် ဤနေရာသို့ဖိဆွဲပါ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"အနည်းဆုံး <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ကွက် ရှိရမည်"</string>
<string name="qs_edit" msgid="5583565172803472437">"တည်းဖြတ်ရန်"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"အချိန်"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"နာရီ၊ မိနစ်နှင့် စက္ကန့်ကိုပြပါ"</item>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 2bd239043dea..75221239f686 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ပိတ်"</item>
<item msgid="4875147066469902392">"ဖွင့်"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"မရနိုင်ပါ"</item>
+ <item msgid="8589336868985358191">"ပိတ်"</item>
+ <item msgid="726072717827778234">"ဖွင့်"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"မရနိုင်ပါ"</item>
<item msgid="5044688398303285224">"ပိတ်"</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 627ab44fba26..82aeb65157d3 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klikk for å koble til en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forhåndsinnstilling"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Når du deler en app, er alt som vises eller spilles av i appen, synlig for <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Del skjermen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktivert dette alternativet"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velg app å dele"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vil du caste skjermen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast én app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Dra hit for å fjerne"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Du trenger minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> infobrikker"</string>
<string name="qs_edit" msgid="5583565172803472437">"Endre"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Vis timer, minutter og sekunder"</item>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index fca868e98240..975c1c1c0b78 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Av"</item>
<item msgid="4875147066469902392">"På"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Utilgjengelig"</item>
+ <item msgid="8589336868985358191">"Av"</item>
+ <item msgid="726072717827778234">"På"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Utilgjengelig"</item>
<item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 6090ca509036..78164a250f42 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नयाँ डिभाइसमा कनेक्ट गर्न क्लिक गर्नुहोस्"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रिसेट अपडेट गर्न सकिएन"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"पूर्वनिर्धारित"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चयन गरिएको छ"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"वरपरका आवाज"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बायाँ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"तपाईंले यो एप सेयर गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> मा देखिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रिन सेयर गर्नुहोस्"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले यो विकल्प अफ गर्नुभएको छ"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"सेयर गर्न छनौट गर्नुहोस्"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"स्क्रिन कास्ट गर्ने हो?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एउटा एप कास्ट गर्नुहोस्"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"हटाउनका लागि यहाँ तान्नुहोस्"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"तपाईंलाई कम्तीमा <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> वटा टाइल चाहिन्छ"</string>
<string name="qs_edit" msgid="5583565172803472437">"सम्पादन गर्नुहोस्"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"समय"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"घन्टा, मिनेट, र सेकेन्ड देखाउनुहोस्"</item>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 71f415a3d0ef..f48daa32df9e 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"अफ छ"</item>
<item msgid="4875147066469902392">"अन छ"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"उपलब्ध छैन"</item>
+ <item msgid="8589336868985358191">"अफ छ"</item>
+ <item msgid="726072717827778234">"अन छ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"उपलब्ध छैन"</item>
<item msgid="5044688398303285224">"अफ छ"</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index ebe9ad475229..fe6f34814279 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nieuw apparaat te koppelen"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorinstelling"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Geselecteerd"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgevingsgeluid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Als je een app deelt, is alles dat wordt getoond of afgespeeld in die app zichtbaar voor <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Scherm delen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Voor <xliff:g id="APP_NAME">%1$s</xliff:g> staat deze optie uit"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"App kiezen om te delen"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Je scherm casten?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Eén app casten"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Sleep hier naartoe om te verwijderen"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Je hebt minimaal <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tegels nodig"</string>
<string name="qs_edit" msgid="5583565172803472437">"Bewerken"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tijd"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Uren, minuten en seconden tonen"</item>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 01de4cbc574f..b739fa2211b3 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Uit"</item>
<item msgid="4875147066469902392">"Aan"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Niet beschikbaar"</item>
+ <item msgid="8589336868985358191">"Uit"</item>
+ <item msgid="726072717827778234">"Aan"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Niet beschikbaar"</item>
<item msgid="5044688398303285224">"Uit"</item>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 8569c7aaad2e..fa16f28f15a8 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ନୂଆ ଡିଭାଇସ ପେୟାର କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ପ୍ରିସେଟ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ଚୟନ କରାଯାଇଛି"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ପରିପାର୍ଶ୍ୱ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ବାମ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ଆପଣ ଏକ ଆପ ସେୟାର କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛି <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>କୁ ଦେଖାଯାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ସ୍କ୍ରିନ ସେୟାର କରନ୍ତୁ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଏହି ବିକଳ୍ପକୁ ଅକ୍ଷମ କରିଛି"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ସେୟାର କରିବାକୁ ଆପ ବାଛନ୍ତୁ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ କାଷ୍ଟ କରିବେ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ଗୋଟିଏ ଆପକୁ କାଷ୍ଟ କରନ୍ତୁ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍‍ କରନ୍ତୁ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍‌ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
<string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ କରନ୍ତୁ"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ସମୟ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ଘଣ୍ଟା, ମିନିଟ୍‍ ଏବଂ ସେକେଣ୍ଡ ଦେଖାନ୍ତୁ"</item>
@@ -1249,7 +1257,7 @@
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ଅଡିଓ ଆଉଟପୁଟ ପାଇଁ ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକ।"</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ଭଲ୍ୟୁମ"</string>
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
- <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string>
+ <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେ"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string>
<string name="media_input_group_title" msgid="2057057473860783021">"ଇନପୁଟ"</string>
<string name="media_output_group_title" msgid="6789001895863332576">"ଆଉଟପୁଟ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c7735a21b25b..98d56e34a6b0 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"\'ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ\' \'ਤੇ ਕਲਿੱਕ ਕਰੋ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ਪ੍ਰੀਸੈੱਟ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ਪ੍ਰੀਸੈੱਟ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ਚੁਣਿਆ ਗਿਆ"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"ਆਲੇ-ਦੁਆਲੇ"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ਖੱਬੇ"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ਕਿਸੇ ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਦੌਰਾਨ, ਉਸ ਐਪ \'ਤੇ ਦਿਖ ਰਹੀ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਨੂੰ ਦਿਖਣਯੋਗ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕਰੋ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੇ ਇਸ ਵਿਕਲਪ ਨੂੰ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ਸਾਂਝਾ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ਕੀ ਸਕ੍ਰੀਨ ਨੂੰ ਕਾਸਟ ਕਰਨਾ ਹੈ?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ਇੱਕ ਐਪ ਨੂੰ ਕਾਸਟ ਕਰੋ"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ਹਟਾਉਣ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ਤੁਹਾਨੂੰ ਘੱਟੋ-ਘੱਟ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ਟਾਇਲਾਂ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string>
<string name="qs_edit" msgid="5583565172803472437">"ਸੰਪਾਦਨ ਕਰੋ"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"ਸਮਾਂ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ਘੰਟੇ, ਮਿੰਟ, ਅਤੇ ਸਕਿੰਟ ਦਿਖਾਓ"</item>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 43b8734bb274..d0f5103c32a1 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ਬੰਦ ਹੈ"</item>
<item msgid="4875147066469902392">"ਚਾਲੂ ਹੈ"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+ <item msgid="8589336868985358191">"ਬੰਦ"</item>
+ <item msgid="726072717827778234">"ਚਾਲੂ"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"ਅਣਉਪਲਬਧ ਹੈ"</item>
<item msgid="5044688398303285224">"ਬੰਦ ਹੈ"</item>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 7c490736651c..cdf30a992f49 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Gotowe ustawienie"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Wybrano"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Otoczenie"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Po lewej"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kiedy udostępniasz obraz z aplikacji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, widoczne jest wszystko to, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Udostępnij ekran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Wybierz aplikację do udostępniania"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści z ekranu?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z 1 aplikacji"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Przeciągnij tutaj, by usunąć"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalna liczba kafelków to <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Edytuj"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Godzina"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Pokazuj godziny, minuty i sekundy"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 40b85cc0da14..d9bbaf064da1 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando você compartilha um aplicativo, todas as informações mostradas ou abertas nele ficam visíveis para o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartilhar tela"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha um app para compartilhar"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arraste aqui para remover"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Horas"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 934c7176d4a3..913f5b3be8bd 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para sincronizar um novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerda"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando está a partilhar uma app, tudo o que é mostrado ou reproduzido nessa app é visível para a app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partilhar ecrã"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou esta opção"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha uma app para partilhar"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir o ecrã?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir uma app"</string>
@@ -794,8 +800,7 @@
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada – Com base no rosto"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
- <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
- <skip />
+ <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Desativar"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"Predefinição"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -980,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastar para aqui para remover"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Necessita de, pelo menos, <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> cartões"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index 42a465ea415f..bedcab0eabc4 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Desligado"</item>
<item msgid="4875147066469902392">"Ligado"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Indisponível"</item>
+ <item msgid="8589336868985358191">"Desativado"</item>
+ <item msgid="726072717827778234">"Ativado"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponível"</item>
<item msgid="5044688398303285224">"Desligada"</item>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 40b85cc0da14..d9bbaf064da1 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando você compartilha um aplicativo, todas as informações mostradas ou abertas nele ficam visíveis para o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartilhar tela"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha um app para compartilhar"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arraste aqui para remover"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Horas"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 3f8324e3b7f3..906ee09405c3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Dă clic pentru a asocia un nou dispozitiv"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Presetare"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selectat"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Împrejurimi"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Stânga"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Când permiți accesul la o aplicație, orice conținut se afișează sau se redă în aplicație este vizibil pentru <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Permite accesul la ecran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a dezactivat această opțiune"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Alege aplicația de trimis"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Proiectezi ecranul?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Proiectează o aplicație"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Trage aici pentru a elimina"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Ai nevoie de cel puțin <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> carduri"</string>
<string name="qs_edit" msgid="5583565172803472437">"Editează"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Oră"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Afișează orele, minutele și secundele"</item>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index 56460771381d..3f893fab4db2 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Dezactivată"</item>
<item msgid="4875147066469902392">"Activată"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Indisponibil"</item>
+ <item msgid="8589336868985358191">"Dezactivat"</item>
+ <item msgid="726072717827778234">"Activat"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Indisponibilă"</item>
<item msgid="5044688398303285224">"Dezactivată"</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 450d048da5bf..ee9d755088ed 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрано"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружающие звуки"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левый"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"При показе приложения все, что в нем происходит, будет видно в приложении \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\". Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Показать экран"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" отключило эту возможность"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Выбор приложения для демонстрации"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Начать трансляцию экрана?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Транслировать одно приложение"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Чтобы удалить, перетащите сюда"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Должно остаться не менее <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> элементов"</string>
<string name="qs_edit" msgid="5583565172803472437">"Изменить"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Время"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Часы, минуты и секунды"</item>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 9ffa7f1f4152..d20f5e218806 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Откл."</item>
<item msgid="4875147066469902392">"Вкл."</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Недоступно"</item>
+ <item msgid="8589336868985358191">"Отключено"</item>
+ <item msgid="726072717827778234">"Включено"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Функция недоступна"</item>
<item msgid="5044688398303285224">"Откл."</item>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c6326f27c478..583d8842b189 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"නව උපාංගය යුගල කිරීමට ක්ලික් කරන්න"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"පෙර සැකසීම යාවත්කාලීන කළ නොහැකි විය"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"පෙරසැකසුම"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"තෝරන ලදි"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"වටපිටාව"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"වම"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ඔබ යෙදුමක් බෙදා ගන්නා විට, එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයක් <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> වෙත දෘශ්‍යමාන වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවිඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"තිරය බෙදා ගන්න"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම විකල්පය අබල කර ඇත"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"බෙදා ගැනීමට යෙදුම තෝරන්න"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ඔබේ තිරය විකාශය කරන්න ද?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"එක් යෙදුමක් විකාශය කරන්න"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ඉවත් කිරීමට මෙතැනට අදින්න"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ඔබ අවම වශයෙන් ටයිල් <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ක් අවශ්‍ය වෙයි"</string>
<string name="qs_edit" msgid="5583565172803472437">"සංස්කරණය"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"වේලාව"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"පැය, මිනිත්තු, සහ තත්පර පෙන්වන්න"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index fe1dbbd926d1..206e10c6245d 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predvoľba"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybrané"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolie"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vľavo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Pri zdieľaní aplikácie vidí aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> všetko, čo sa v zdieľanej aplikácii zobrazuje alebo prehráva. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Zdieľať obrazovku"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> túto možnosť zakázala"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vyberte aplikáciu, do ktorej chcete zdieľať"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Chcete prenášať obrazovku?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Prenášať jednu aplikáciu"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Presunutím sem odstránite"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimálny počet vyžadovaných dlaždíc: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Upraviť"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Čas"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Zobrazovať hodiny, minúty a sekundy"</item>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 5a4ce99bf63e..1b82be8eab8e 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Vypnuté"</item>
<item msgid="4875147066469902392">"Zapnuté"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nedostupné"</item>
+ <item msgid="8589336868985358191">"Vypnutý"</item>
+ <item msgid="726072717827778234">"Zapnutý"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nie je k dispozícii"</item>
<item msgid="5044688398303285224">"Vypnuté"</item>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 22d21bc47731..1c1ff03c3dcf 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite za seznanitev nove naprave"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Prednastavljeno"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izbrano"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolica"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Pri deljenju aplikacije je aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vidno vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deli zaslon"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Izbira aplikacije za deljenje"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite predvajati vsebino zaslona?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje ene aplikacije"</string>
@@ -794,8 +800,7 @@
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Vklopljeno – na podlagi obraza"</string>
<string name="inline_done_button" msgid="6043094985588909584">"Končano"</string>
<string name="inline_ok_button" msgid="603075490581280343">"Uporabi"</string>
- <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
- <skip />
+ <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Izklopi"</string>
<string name="notification_silence_title" msgid="8608090968400832335">"Tiho"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"Privzeto"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string>
@@ -980,6 +985,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Če želite odstraniti, povlecite sem"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Imeti morate vsaj toliko ploščic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Uredi"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ura"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Prikaži ure, minute in sekunde"</item>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index 8f243dedef9c..e0db4f1d262a 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Izklopljeno"</item>
<item msgid="4875147066469902392">"Vklopljeno"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Ni na voljo"</item>
+ <item msgid="8589336868985358191">"Izklopljeno"</item>
+ <item msgid="726072717827778234">"Vklopljeno"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ni na voljo"</item>
<item msgid="5044688398303285224">"Izklopljeno"</item>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 203b9faa6730..c68e7a81a02c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliko për të çiftuar një pajisje të re"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Paravendosja"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Zgjedhur"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambienti rrethues"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Majtas"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kur ti ndan një aplikacion, çdo gjë që shfaqet ose luhet në atë aplikacion është e dukshme për <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ndaj ekranin"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> e ka çaktivizuar këtë opsion"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Zgjidh aplikacionin për të ndarë"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Të transmetohet ekrani yt?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmeto një aplikacion"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Zvarrit këtu për ta hequr"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Të duhen të paktën <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pllakëza"</string>
<string name="qs_edit" msgid="5583565172803472437">"Redakto"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Ora"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Shfaq orët, minutat dhe sekondat"</item>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index ac1409990bcd..9bbb0f941ab1 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Joaktiv"</item>
<item msgid="4875147066469902392">"Aktiv"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Nuk ofrohet"</item>
+ <item msgid="8589336868985358191">"Çaktivizuar"</item>
+ <item msgid="726072717827778234">"Aktivizuar"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nuk ofrohet"</item>
<item msgid="5044688398303285224">"Joaktiv"</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 97ca62a420c3..46d83528114f 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Унапред одређена подешавања"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Изабрано"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружење"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Када делите апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> види сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Дели екран"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућила ову опцију"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Одаберите апликацију за дељење"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Желите да пребаците екран?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Пребаци једну апликацију"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Превуците овде да бисте уклонили"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Минималан број плочица је <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Време"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Прикажи сате, минуте и секунде"</item>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index e7e34aea2bee..14a8d94d2839 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Искључено"</item>
<item msgid="4875147066469902392">"Укључено"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Недоступно"</item>
+ <item msgid="8589336868985358191">"Искључено"</item>
+ <item msgid="726072717827778234">"Укључено"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Недоступно"</item>
<item msgid="5044688398303285224">"Искључено"</item>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 4cdc37d72176..ed0daf9da04b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicka för att parkoppla en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Förinställning"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Markerad"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivningsläge"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vänster"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"När du delar en app är allt som visas eller spelas upp i appen synligt för <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dela skärmen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inaktiverat alternativet"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Välj en app att dela"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vill du casta skärmen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Casta en app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Ta bort genom att dra här"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> rutor måste finnas kvar"</string>
<string name="qs_edit" msgid="5583565172803472437">"Redigera"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Visa timmar, minuter och sekunder"</item>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index 7ec70eac7adc..f042697bd74d 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Av"</item>
<item msgid="4875147066469902392">"På"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Inte tillgängligt"</item>
+ <item msgid="8589336868985358191">"Av"</item>
+ <item msgid="726072717827778234">"På"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Inte tillgängligt"</item>
<item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 1cb61fdbab01..da390fb459ac 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Mipangilio iliyowekwa mapema"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Umechagua"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Mazingira"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kushoto"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Unaporuhusu ufikiaji wa programu, chochote kinachoonyeshwa au kuchezwa katika programu hiyo kitaonekana kwa <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ruhusu ufikiaji wa skrini"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezima chaguo hili"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Chagua programu utakayoruhusu ifikiwe"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ungependa kutuma maudhui yaliyo katika skrini yako?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Tuma maudhui ya programu moja"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Buruta hapa ili uondoe"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Unahitaji angalau vigae <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Badilisha"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Wakati"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Onyesha saa, dakika na sekunde"</item>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 9e262819f560..e08ed3a107da 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Kimezimwa"</item>
<item msgid="4875147066469902392">"Kimewashwa"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Haipatikani"</item>
+ <item msgid="8589336868985358191">"Imezimwa"</item>
+ <item msgid="726072717827778234">"Imewashwa"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Hakipatikani"</item>
<item msgid="5044688398303285224">"Imezimwa"</item>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 3109a13290af..0c7aa40868cb 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"புதிய சாதனத்தை இணைக்க கிளிக் செய்யலாம்"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"முன்னமைவைப் புதுப்பிக்க முடியவில்லை"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"முன்னமைவு"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"தேர்ந்தெடுக்கப்பட்டது"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"சுற்றுப்புறங்கள்"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"இடது"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ஓர் ஆப்ஸைப் பகிரும்போது, அதில் காட்டப்படும்/பிளே செய்யப்படும் அனைத்தும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> இல் தெரியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"திரையைப் பகிர்"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இந்த விருப்பத்தை முடக்கியுள்ளது"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"பகிர ஆப்ஸைத் தேர்வுசெய்க"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"உங்கள் திரையை அலைபரப்ப வேண்டுமா?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ஓர் ஆப்ஸை அலைபரப்பு"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"அகற்ற, இங்கே இழுக்கவும்"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"குறைந்தது <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> கட்டங்கள் தேவை"</string>
<string name="qs_edit" msgid="5583565172803472437">"மாற்று"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"நேரம்"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"மணிநேரம், நிமிடங்கள், வினாடிகளைக் காட்டு"</item>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index d3773a761c37..8280da4340e9 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"முடக்கப்பட்டுள்ளது"</item>
<item msgid="4875147066469902392">"இயக்கப்பட்டுள்ளது"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"கிடைக்கவில்லை"</item>
+ <item msgid="8589336868985358191">"ஆஃப்"</item>
+ <item msgid="726072717827778234">"ஆன்"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"கிடைக்கவில்லை"</item>
<item msgid="5044688398303285224">"முடக்கப்பட்டுள்ளது"</item>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 1bf3ab2e913f..972c64ab7f26 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"కొత్త పరికరాన్ని పెయిర్ చేయడానికి క్లిక్ చేయండి"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ప్రీసెట్‌ను అప్‌డేట్ చేయడం సాధ్యపడలేదు"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ప్రీసెట్"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ఎంచుకోబడింది"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"పరిసరాలు"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ఎడమ వైపునకు"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"మీరు యాప్‌ను షేర్ చేసేటప్పుడు, సంబంధిత యాప్‌లో కనిపించేవి లేదా ప్లే అయ్యేవన్నీ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>‌కు కనిపిస్తాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"స్క్రీన్‌ను షేర్ చేయండి"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ఈ ఆప్షన్‌ను డిజేబుల్ చేసింది"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"షేర్ చేయడానికి యాప్‌ను ఎంచుకోండి"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"మీ స్క్రీన్‌ను ప్రసారం చేయాలా?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ఒక యాప్‌ను ప్రసారం చేయండి"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"తీసివేయడానికి ఇక్కడికి లాగండి"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"మీ వద్ద కనీసం <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> టైల్‌లు ఉండాలి"</string>
<string name="qs_edit" msgid="5583565172803472437">"ఎడిట్ చేయండి"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"సమయం"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"గంటలు, నిమిషాలు మరియు సెకన్లను చూపు"</item>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 72343a33a082..60a91f82ca9b 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"ఆఫ్‌లో ఉంది"</item>
<item msgid="4875147066469902392">"ఆన్‌లో ఉంది"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"అందుబాటులో లేదు"</item>
+ <item msgid="8589336868985358191">"ఆఫ్‌లో ఉంది"</item>
+ <item msgid="726072717827778234">"ఆన్‌లో ఉంది"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"అందుబాటులో లేదు"</item>
<item msgid="5044688398303285224">"ఆఫ్‌లో ఉంది"</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 99aca811b873..a4f14473e004 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"คลิกเพื่อจับคู่อุปกรณ์ใหม่"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ไม่สามารถอัปเดตค่าที่กำหนดล่วงหน้า"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ค่าที่กำหนดล่วงหน้า"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"เลือกแล้ว"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"เสียงแวดล้อม"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ซ้าย"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"เมื่อกำลังแชร์แอป <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะมองเห็นทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"แชร์หน้าจอ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ปิดใช้ตัวเลือกนี้"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"เลือกแอปที่จะแชร์"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"แคสต์หน้าจอของคุณไหม"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"แคสต์แอปเดียว"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ลากมาที่นี่เพื่อนำออก"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"คุณต้องมีการ์ดอย่างน้อย <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> รายการ"</string>
<string name="qs_edit" msgid="5583565172803472437">"แก้ไข"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"เวลา"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"แสดงชั่วโมง นาที และวินาที"</item>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 726cf21e84e4..1f251758db94 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"I-click para magpares ng bagong device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Napili"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Paligid"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kaliwa"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kapag nagshe-share ka ng app, makikita ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ibahagi ang screen"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Na-disable ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang opsyong ito"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pumili ng app na ishe-share"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"I-cast ang iyong screen?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Mag-cast ng isang app"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"I-drag dito upang alisin"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Kailangan mo ng kahit <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> (na) tile"</string>
<string name="qs_edit" msgid="5583565172803472437">"I-edit"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Oras"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Ipakita ang oras, minuto at segundo"</item>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 92a122dcf437..84213d5a51c3 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Naka-off"</item>
<item msgid="4875147066469902392">"Naka-on"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Hindi available"</item>
+ <item msgid="8589336868985358191">"Naka-off"</item>
+ <item msgid="726072717827778234">"Naka-on"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Hindi available"</item>
<item msgid="5044688398303285224">"Naka-off"</item>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index a68bc74df470..4748cc4dad54 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz eşlemek için tıklayın"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçili"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Çevredeki sesler"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, bir uygulamayı paylaştığınızda o uygulamada gösterilen veya oynatılan her şeyi görebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranı paylaş"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçeneği devre dışı bıraktı"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Paylaşılacak uygulamayı seçin"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekranınız yayınlansın mı?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"1 uygulamayı yayınla"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kaldırmak için buraya sürükleyin"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"En az <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kutu gerekiyor"</string>
<string name="qs_edit" msgid="5583565172803472437">"Düzenle"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Saat"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Saati, dakikayı ve saniyeyi göster"</item>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 986981f21237..3efa8ea96fb3 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Kapalı"</item>
<item msgid="4875147066469902392">"Açık"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Kullanılamıyor"</item>
+ <item msgid="8589336868985358191">"Kapalı"</item>
+ <item msgid="726072717827778234">"Açık"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Kullanılamıyor"</item>
<item msgid="5044688398303285224">"Kapalı"</item>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2e0229393897..d89467cf5e23 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Натисніть, щоб підключити новий пристрій"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Вибрано"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Звуки оточення"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ліворуч"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Коли ви показуєте вікно додатка, увесь контент, що відображається або відтворюється в ньому, стає видимим у додатку <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Тому будьте обережні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Показати екран"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> вимкнув цю опцію"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Виберіть додаток для показу"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Транслювати екран?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Транслювати один додаток"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Перетягніть сюди, щоб видалити"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Мінімальна кількість фрагментів: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Редагувати"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Час"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Показувати години, хвилини та секунди"</item>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c5a96096a86b..51950e099640 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"نئے آلے کا جوڑا بنانے کے لیے کلک کریں"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"پہلے سے ترتیب شدہ کو اپ ڈیٹ نہیں کیا جا سکا"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"پہلے سے ترتیب شدہ"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"منتخب کردہ"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"اطراف"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"دائیں"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"آپ کے کسی ایپ کا اشتراک کرنے پر اس ایپ میں دکھائی گئی یا چلائی گئی ہر چیز <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کیلئے مرئی ہو جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"اسکرین کا اشتراک کریں"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> نے اس اختیار کو غیر فعال کر دیا ہے"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"اشتراک کرنے کیلئے ایپ منتخب کریں"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"اپنی اسکرین کاسٹ کریں؟"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ایک ایپ کاسٹ کریں"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ہٹانے کیلئے یہاں گھسیٹیں؟"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"آپ کو کم از کم <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ٹائلز کی ضرورت ہے"</string>
<string name="qs_edit" msgid="5583565172803472437">"ترمیم کریں"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"وقت"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"گھنٹے، منٹ اور سیکنڈ دکھائیں"</item>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index ea032f1451bd..88698b5c7514 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"آف ہے"</item>
<item msgid="4875147066469902392">"آن ہے"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"دستیاب نہیں ہے"</item>
+ <item msgid="8589336868985358191">"آف"</item>
+ <item msgid="726072717827778234">"آن"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"دستیاب نہیں ہے"</item>
<item msgid="5044688398303285224">"آف ہے"</item>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index fee0eb9c5473..8d750dd8ad08 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Andoza"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Tanlangan"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Atrof-muhit"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Chap"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Ilovani namoyish qilayotganingizda oʻsha ilova ichida koʻrsatilayotgan yoki ijro qilinayotganlar <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ga koʻrinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranni namoyish qilish"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu sozlamani faolsizlantirgan"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Ulashiladigan ilovani tanlash"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekraningiz uzatilsinmi?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Bitta ilovani uzatish"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"O‘chirish uchun bu yerga torting"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Kamida <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ta katakcha lozim"</string>
<string name="qs_edit" msgid="5583565172803472437">"Tahrirlash"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Vaqt"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Soat, daqiqa va soniyalar ko‘rsatilsin"</item>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 1433a9b79071..7afb9bdc8034 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Oʻchiq"</item>
<item msgid="4875147066469902392">"Yoniq"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Mavjud emas"</item>
+ <item msgid="8589336868985358191">"Yoqilmagan"</item>
+ <item msgid="726072717827778234">"Yoniq"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Ishlamaydi"</item>
<item msgid="5044688398303285224">"Oʻchiq"</item>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c79eef76e6e4..300dea9bb021 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Nhấp để ghép nối thiết bị mới"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Chế độ đặt sẵn"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Đã chọn"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Âm lượng xung quanh"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Trái"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Khi bạn chia sẻ một ứng dụng, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ thấy được mọi nội dung hiển thị hoặc phát trong ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Chia sẻ màn hình"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> đã tắt lựa chọn này"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Chọn ứng dụng để chia sẻ"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Truyền màn hình?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Truyền một ứng dụng"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kéo vào đây để xóa"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Bạn cần ít nhất <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ô"</string>
<string name="qs_edit" msgid="5583565172803472437">"Chỉnh sửa"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Thời gian"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Hiển thị giờ, phút và giây"</item>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 02d2bb6be45f..78e39a75e117 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Đang tắt"</item>
<item msgid="4875147066469902392">"Đang bật"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Không có"</item>
+ <item msgid="8589336868985358191">"Đang tắt"</item>
+ <item msgid="726072717827778234">"Đang bật"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Không hoạt động"</item>
<item msgid="5044688398303285224">"Đang tắt"</item>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index f0f55a827930..dacca692fb65 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"点击即可与新设备配对"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"无法更新预设"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"预设"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已选择"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"周围声音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左侧"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"当您共享一个应用时,该应用中显示或播放的所有内容均对“<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>”可见。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"共享屏幕"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已停用此选项"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"选择要分享的应用"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"投放您的屏幕?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放单个应用"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖动到此处即可移除"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"您至少需要 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 个卡片"</string>
<string name="qs_edit" msgid="5583565172803472437">"编辑"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"时间"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"显示小时、分钟和秒"</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index caac7437b4e0..afc33d9611b9 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"㩒一下就可以配對新裝置"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"揀咗"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境聲音"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"當你分享應用程式時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可看到該應用程式中顯示或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"分享螢幕畫面"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"選擇要分享的應用程式"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"要投放螢幕嗎?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放一個應用程式"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳這裡即可移除"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"你需要有至少 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
<string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"時間"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"顯示小時、分鐘和秒"</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index 7369d9519b34..2dcb0cd290e1 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"已關閉"</item>
<item msgid="4875147066469902392">"已開啟"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"無法使用"</item>
+ <item msgid="8589336868985358191">"已關閉"</item>
+ <item msgid="726072717827778234">"已開啟"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"無法使用"</item>
<item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d3a5544ac694..3ea590a17188 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -419,6 +419,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"按一下即可配對新裝置"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設設定"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已選取"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
@@ -582,6 +586,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"當你分享應用程式畫面時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取該應用程式顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"分享畫面"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"選擇要分享的應用程式"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"要投放畫面嗎?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放一個應用程式"</string>
@@ -980,6 +986,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳到這裡即可移除"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"你至少必須要有 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個設定方塊"</string>
<string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"時間"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"顯示小時、分鐘和秒"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 18a6d12dcff9..33313ac14d53 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"已關閉"</item>
<item msgid="4875147066469902392">"已開啟"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"無法使用"</item>
+ <item msgid="8589336868985358191">"已關閉"</item>
+ <item msgid="726072717827778234">"已開啟"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"無法使用"</item>
<item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 08657d1bfe54..767adbb25c25 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -421,6 +421,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Chofoza ukuze ubhangqe idivayisi entsha"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ukusetha ngaphambilini"</string>
+ <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+ <skip />
+ <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+ <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
<string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Okukhethiwe"</string>
<string name="hearing_devices_ambient_label" msgid="629440938614895797">"Izindawo ezizungezile"</string>
<string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kwesokunxele"</string>
@@ -584,6 +588,8 @@
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Uma wabelana nge-app, noma yini eboniswayo noma edlalwayo kuleyo app ibonakala ku-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Yabelana ngesikrini"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ivale le nketho"</string>
+ <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+ <skip />
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Khetha i-app yokwabelana"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Sakaza isikrini sakho?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Sakaza i-app eyodwa"</string>
@@ -982,6 +988,8 @@
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Hudulela lapha ukuze ususe"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"Udinga okungenani amathayela angu-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
<string name="qs_edit" msgid="5583565172803472437">"Hlela"</string>
+ <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+ <skip />
<string name="tuner_time" msgid="2450785840990529997">"Isikhathi"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"Bonisa amahora, amaminithi, namasekhondi"</item>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 674aeaa3b890..10b26fc31dce 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -56,9 +56,11 @@
<item msgid="5376619709702103243">"Valiwe"</item>
<item msgid="4875147066469902392">"Vuliwe"</item>
</string-array>
- <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
- <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
- <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
+ <string-array name="tile_states_modes_dnd">
+ <item msgid="6509540227356524582">"Ayitholakali"</item>
+ <item msgid="8589336868985358191">"Valiwe"</item>
+ <item msgid="726072717827778234">"Vuliwe"</item>
+ </string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Akutholakali"</item>
<item msgid="5044688398303285224">"Valiwe"</item>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7895ff7b90f6..a479f1841ca4 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -19,7 +19,8 @@
<style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
<item name="android:textSize">@dimen/status_bar_clock_size</item>
- <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:fontFamily" android:featureFlag="!com.android.systemui.status_bar_font_updates">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:fontFamily" android:featureFlag="com.android.systemui.status_bar_font_updates">"variable-label-large-emphasized"</item>
<item name="android:textColor">@color/status_bar_clock_color</item>
<item name="android:fontFeatureSettings">tnum</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 089466707298..d017754ae653 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -778,18 +778,26 @@ public class SwipeHelper implements Gefingerpoken, Dumpable {
protected boolean swipedFarEnough() {
float translation = getTranslation(mTouchedView);
- return Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(
- mTouchedView);
+ return Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(mTouchedView);
}
public boolean isDismissGesture(MotionEvent ev) {
float translation = getTranslation(mTouchedView);
return ev.getActionMasked() == MotionEvent.ACTION_UP
&& !mFalsingManager.isUnlockingDisabled()
- && !isFalseGesture() && (swipedFastEnough() || swipedFarEnough())
+ && !isFalseGesture() && isSwipeDismissible()
&& mCallback.canChildBeDismissedInDirection(mTouchedView, translation > 0);
}
+ /** Can the swipe gesture on the touched view be considered as a dismiss intention */
+ public boolean isSwipeDismissible() {
+ if (magneticNotificationSwipes()) {
+ return mCallback.isMagneticViewDetached(mTouchedView) || swipedFastEnough();
+ } else {
+ return swipedFastEnough() || swipedFarEnough();
+ }
+ }
+
/** Returns true if the gesture should be rejected. */
public boolean isFalseGesture() {
boolean falsingDetected = mCallback.isAntiFalsingNeeded();
@@ -970,6 +978,13 @@ public class SwipeHelper implements Gefingerpoken, Dumpable {
void onMagneticInteractionEnd(View view, float velocity);
/**
+ * Determine if a view managed by magnetic interactions is magnetically detached
+ * @param view The magnetic view
+ * @return if the view is detached according to its magnetic state.
+ */
+ boolean isMagneticViewDetached(View view);
+
+ /**
* Called when the child is long pressed and available to start drag and drop.
*
* @param v the view that was long pressed.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index 14b13d105482..24b955152093 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -286,7 +286,9 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
mLaunchSourceId);
final Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_DETAILS_SETTINGS)
.putExtra(Intent.EXTRA_COMPONENT_NAME,
- ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+ ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString())
+ .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
+
mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
mDialogTransitionAnimator.createActivityTransitionController(
dialog));
@@ -588,9 +590,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
com.android.internal.R.color.materialColorOnPrimaryContainer));
}
text.setText(item.getToolName());
- Intent intent = item.getToolIntent()
- .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
-
+ Intent intent = item.getToolIntent();
view.setOnClickListener(v -> {
final String name = intent.getComponent() != null
? intent.getComponent().flattenToString()
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index da1c1bc49d23..2d44d401b0b0 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -130,6 +130,8 @@ public class AssistManager {
AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS;
public static final int INVOCATION_TYPE_NAV_HANDLE_LONG_PRESS =
AssistUtils.INVOCATION_TYPE_NAV_HANDLE_LONG_PRESS;
+ public static final int INVOCATION_TYPE_LAUNCHER_SYSTEM_SHORTCUT =
+ AssistUtils.INVOCATION_TYPE_LAUNCHER_SYSTEM_SHORTCUT;
public static final int DISMISS_REASON_INVOCATION_CANCELLED = 1;
public static final int DISMISS_REASON_TAP = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
index 3520439fda88..a8f21885907b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.dagger
import com.android.app.displaylib.DefaultDisplayOnlyInstanceRepositoryImpl
import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
import com.android.app.displaylib.PerDisplayRepository
+import com.android.systemui.display.data.repository.PerDisplayCoroutineScopeRepositoryModule
import com.android.systemui.model.SysUIStateInstanceProvider
import com.android.systemui.model.SysUiState
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
@@ -26,7 +27,7 @@ import dagger.Module
import dagger.Provides
/** This module is meant to contain all the code to create the various [PerDisplayRepository<>]. */
-@Module
+@Module(includes = [PerDisplayCoroutineScopeRepositoryModule::class])
class PerDisplayRepositoriesModule {
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
index 908d0aafb2b9..32b69e5423ba 100644
--- a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
@@ -29,10 +29,10 @@ import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.display.data.repository.DeviceStateRepositoryImpl
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayRepositoryImpl
-import com.android.systemui.display.data.repository.DisplayScopeRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepositoryImpl
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepositoryImpl
+import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepository
+import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepositoryImpl
import com.android.systemui.display.data.repository.FocusedDisplayRepository
import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
import com.android.systemui.display.data.repository.PerDisplayRepoDumpHelper
@@ -76,14 +76,17 @@ interface DisplayModule {
focusedDisplayRepository: FocusedDisplayRepositoryImpl
): FocusedDisplayRepository
- @Binds fun displayScopeRepository(impl: DisplayScopeRepositoryImpl): DisplayScopeRepository
-
@Binds
fun displayWindowPropertiesRepository(
impl: DisplayWindowPropertiesRepositoryImpl
): DisplayWindowPropertiesRepository
@Binds
+ fun displaysWithDecorationsRepository(
+ impl: DisplaysWithDecorationsRepositoryImpl
+ ): DisplaysWithDecorationsRepository
+
+ @Binds
fun dumpRegistrationLambda(helper: PerDisplayRepoDumpHelper): PerDisplayRepository.InitCallback
@Binds
@@ -94,20 +97,6 @@ interface DisplayModule {
@Provides
@SysUISingleton
@IntoMap
- @ClassKey(DisplayScopeRepositoryImpl::class)
- fun displayScopeRepoCoreStartable(
- repoImplLazy: Lazy<DisplayScopeRepositoryImpl>
- ): CoreStartable {
- return if (StatusBarConnectedDisplays.isEnabled) {
- repoImplLazy.get()
- } else {
- CoreStartable.NOP
- }
- }
-
- @Provides
- @SysUISingleton
- @IntoMap
@ClassKey(DisplayWindowPropertiesRepository::class)
fun displayWindowPropertiesRepoAsCoreStartable(
repoLazy: Lazy<DisplayWindowPropertiesRepositoryImpl>
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 051fe7e5517c..01bbf2d57dd6 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -16,95 +16,25 @@
package com.android.systemui.display.data.repository
-import android.annotation.SuppressLint
-import android.view.IWindowManager
import com.android.app.displaylib.DisplayRepository as DisplayRepositoryFromLib
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.statusbar.CommandQueue
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.scan
-import kotlinx.coroutines.flow.stateIn
-/** Repository for providing access to display related information and events. */
-interface DisplayRepository : DisplayRepositoryFromLib {
-
- /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
- val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
-}
+/**
+ * Repository for providing access to display related information and events.
+ *
+ * This is now just an interface that extends [DisplayRepositoryFromLib] to avoid changing all the
+ * imports in sysui using this interface.
+ */
+interface DisplayRepository : DisplayRepositoryFromLib, DisplaysWithDecorationsRepository
@SysUISingleton
-@SuppressLint("SharedFlowCreation")
class DisplayRepositoryImpl
@Inject
constructor(
- private val commandQueue: CommandQueue,
- private val windowManager: IWindowManager,
- @Background bgApplicationScope: CoroutineScope,
private val displayRepositoryFromLib: com.android.app.displaylib.DisplayRepository,
-) : DisplayRepositoryFromLib by displayRepositoryFromLib, DisplayRepository {
-
- private val decorationEvents: Flow<Event> = callbackFlow {
- val callback =
- object : CommandQueue.Callbacks {
- override fun onDisplayAddSystemDecorations(displayId: Int) {
- trySend(Event.Add(displayId))
- }
-
- override fun onDisplayRemoveSystemDecorations(displayId: Int) {
- trySend(Event.Remove(displayId))
- }
- }
- commandQueue.addCallback(callback)
- awaitClose { commandQueue.removeCallback(callback) }
- }
-
- private val initialDisplayIdsWithDecorations: Set<Int> =
- displayIds.value.filter { windowManager.shouldShowSystemDecors(it) }.toSet()
-
- /**
- * A [StateFlow] that maintains a set of display IDs that should have system decorations.
- *
- * Updates to the set are triggered by:
- * - Adding displays via [CommandQueue.Callbacks.onDisplayAddSystemDecorations].
- * - Removing displays via [CommandQueue.Callbacks.onDisplayRemoveSystemDecorations].
- * - Removing displays via [displayRemovalEvent] emissions.
- *
- * The set is initialized with displays that qualify for system decorations based on
- * [WindowManager.shouldShowSystemDecors].
- */
- override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
- merge(decorationEvents, displayRemovalEvent.map { Event.Remove(it) })
- .scan(initialDisplayIdsWithDecorations) { displayIds: Set<Int>, event: Event ->
- when (event) {
- is Event.Add -> displayIds + event.displayId
- is Event.Remove -> displayIds - event.displayId
- }
- }
- .distinctUntilChanged()
- .stateIn(
- scope = bgApplicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = initialDisplayIdsWithDecorations,
- )
-
- private sealed class Event(val displayId: Int) {
- class Add(displayId: Int) : Event(displayId)
-
- class Remove(displayId: Int) : Event(displayId)
- }
-
- private companion object {
- const val TAG = "DisplayRepository"
- }
-}
+ private val displaysWithDecorationsRepositoryImpl: DisplaysWithDecorationsRepository,
+) :
+ DisplayRepositoryFromLib by displayRepositoryFromLib,
+ DisplaysWithDecorationsRepository by displaysWithDecorationsRepositoryImpl,
+ DisplayRepository
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
index d912b6a13d0f..ac59b16bfe3c 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
@@ -17,60 +17,58 @@
package com.android.systemui.display.data.repository
import android.view.Display
-import com.android.systemui.CoreStartable
+import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
+import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.coroutines.newTracingContext
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
-import java.util.concurrent.ConcurrentHashMap
+import dagger.Module
+import dagger.Provides
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
- * Provides per display instances of [CoroutineScope]. These will remain active as long as the
- * display is connected, and automatically cancelled when the display is removed.
+ * Provides per display instances of [CoroutineScope].
+ *
+ * This is used to create a [PerDisplayRepository] of [CoroutineScope]
*/
-interface DisplayScopeRepository {
- fun scopeForDisplay(displayId: Int): CoroutineScope
-}
-
@SysUISingleton
-class DisplayScopeRepositoryImpl
+class DisplayScopeRepositoryInstanceProvider
@Inject
constructor(
@Background private val backgroundApplicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
- private val displayRepository: DisplayRepository,
-) : DisplayScopeRepository, CoreStartable {
-
- private val perDisplayScopes = ConcurrentHashMap<Int, CoroutineScope>()
-
- override fun scopeForDisplay(displayId: Int): CoroutineScope {
- return perDisplayScopes.computeIfAbsent(displayId) { createScopeForDisplay(displayId) }
- }
-
- override fun start() {
- StatusBarConnectedDisplays.unsafeAssertInNewMode()
- backgroundApplicationScope.launch {
- displayRepository.displayRemovalEvent.collect { displayId ->
- val scope = perDisplayScopes.remove(displayId)
- scope?.cancel("Display $displayId has been removed.")
- }
- }
- }
+) : PerDisplayInstanceProviderWithTeardown<CoroutineScope> {
- private fun createScopeForDisplay(displayId: Int): CoroutineScope {
+ override fun createInstance(displayId: Int): CoroutineScope {
return if (displayId == Display.DEFAULT_DISPLAY) {
// The default display is connected all the time, therefore we can optimise by reusing
// the application scope, and don't need to create a new scope.
backgroundApplicationScope
} else {
- CoroutineScope(
- backgroundDispatcher + newTracingContext("DisplayScope$displayId")
- )
+ CoroutineScope(backgroundDispatcher + newTracingContext("DisplayScope$displayId"))
}
}
+
+ override fun destroyInstance(instance: CoroutineScope) {
+ instance.cancel("DisplayContext has been cancelled.")
+ }
+}
+
+@Module
+object PerDisplayCoroutineScopeRepositoryModule {
+ @SysUISingleton
+ @Provides
+ fun provideDisplayCoroutineScopeRepository(
+ repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory<CoroutineScope>,
+ instanceProvider: DisplayScopeRepositoryInstanceProvider,
+ ): PerDisplayRepository<CoroutineScope> {
+ return repositoryFactory.create(
+ debugName = "CoroutineScopePerDisplayRepo",
+ instanceProvider,
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt
new file mode 100644
index 000000000000..f4a2ed48f295
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.display.data.repository
+
+import android.view.IWindowManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.CommandQueue
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.scan
+import kotlinx.coroutines.flow.stateIn
+
+/** Provides the displays with decorations. */
+interface DisplaysWithDecorationsRepository {
+ /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
+ val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
+}
+
+@SysUISingleton
+class DisplaysWithDecorationsRepositoryImpl
+@Inject
+constructor(
+ private val commandQueue: CommandQueue,
+ private val windowManager: IWindowManager,
+ @Background bgApplicationScope: CoroutineScope,
+ displayRepository: com.android.app.displaylib.DisplayRepository,
+) : DisplaysWithDecorationsRepository {
+
+ private val decorationEvents: Flow<Event> = callbackFlow {
+ val callback =
+ object : CommandQueue.Callbacks {
+ override fun onDisplayAddSystemDecorations(displayId: Int) {
+ trySend(Event.Add(displayId))
+ }
+
+ override fun onDisplayRemoveSystemDecorations(displayId: Int) {
+ trySend(Event.Remove(displayId))
+ }
+ }
+ commandQueue.addCallback(callback)
+ awaitClose { commandQueue.removeCallback(callback) }
+ }
+
+ private val initialDisplayIdsWithDecorations: Set<Int> =
+ displayRepository.displayIds.value
+ .filter { windowManager.shouldShowSystemDecors(it) }
+ .toSet()
+
+ /**
+ * A [StateFlow] that maintains a set of display IDs that should have system decorations.
+ *
+ * Updates to the set are triggered by:
+ * - Adding displays via [CommandQueue.Callbacks.onDisplayAddSystemDecorations].
+ * - Removing displays via [CommandQueue.Callbacks.onDisplayRemoveSystemDecorations].
+ * - Removing displays via [displayRemovalEvent] emissions.
+ *
+ * The set is initialized with displays that qualify for system decorations based on
+ * [WindowManager.shouldShowSystemDecors].
+ */
+ override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
+ merge(decorationEvents, displayRepository.displayRemovalEvent.map { Event.Remove(it) })
+ .scan(initialDisplayIdsWithDecorations) { displayIds: Set<Int>, event: Event ->
+ when (event) {
+ is Event.Add -> displayIds + event.displayId
+ is Event.Remove -> displayIds - event.displayId
+ }
+ }
+ .distinctUntilChanged()
+ .stateIn(
+ scope = bgApplicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = initialDisplayIdsWithDecorations,
+ )
+
+ private sealed class Event(val displayId: Int) {
+ class Add(displayId: Int) : Event(displayId)
+
+ class Remove(displayId: Int) : Event(displayId)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
index 46048868f503..8756c8813df6 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
@@ -68,7 +68,7 @@ abstract class PerDisplayStoreImpl<T>(
* displays.
*/
override fun forDisplay(displayId: Int): T? {
- if (displayRepository.getDisplay(displayId) == null) {
+ if (displayRepository.getDisplay(displayId) == null) {
Log.e(TAG, "<${instanceClass.simpleName}>: Display with id $displayId doesn't exist.")
return null
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 9def81a89e3a..2b16e198b1b1 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -18,7 +18,6 @@ package com.android.systemui.doze;
import static com.android.systemui.doze.DozeMachine.State.DOZE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
-import static com.android.systemui.Flags.dozeuiSchedulingAlarmsBackgroundExecution;
import android.app.AlarmManager;
import android.content.Context;
@@ -84,13 +83,7 @@ public class DozeUi implements DozeMachine.Part {
mBgExecutor = bgExecutor;
mCanAnimateTransition = !params.getDisplayNeedsBlanking();
mDozeParameters = params;
- if (dozeuiSchedulingAlarmsBackgroundExecution()) {
- mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick",
- bgHandler);
- } else {
- mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick",
- handler);
- }
+ mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", bgHandler);
mDozeLog = dozeLog;
}
@@ -184,7 +177,7 @@ public class DozeUi implements DozeMachine.Part {
mTimeTickScheduled = true;
long time = System.currentTimeMillis();
- long delta = roundToNextMinute(time) - System.currentTimeMillis();
+ long delta = roundToNextMinute(time) - time;
boolean scheduled = mTimeTicker.schedule(delta, AlarmTimeout.MODE_RESCHEDULE_IF_SCHEDULED);
if (scheduled) {
mDozeLog.traceTimeTickScheduled(time, time + delta);
@@ -224,14 +217,8 @@ public class DozeUi implements DozeMachine.Part {
private void onTimeTick() {
verifyLastTimeTick();
- if (dozeuiSchedulingAlarmsBackgroundExecution()) {
- mHandler.post(mHost::dozeTimeTick);
- } else {
- mHost.dozeTimeTick();
- }
-
// Keep wakelock until a frame has been pushed.
- mHandler.post(mWakeLock.wrap(() -> {}));
+ mHandler.post(mWakeLock.wrap(mHost::dozeTimeTick));
mTimeTickScheduled = false;
scheduleTimeTick();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4755e2845587..6db2ebc0df2c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1744,6 +1744,9 @@ public class KeyguardViewMediator implements CoreStartable,
mJavaAdapter.alwaysCollectFlow(
mWallpaperRepository.getWallpaperSupportsAmbientMode(),
this::setWallpaperSupportsAmbientMode);
+ mJavaAdapter.alwaysCollectFlow(
+ mKeyguardInteractor.getDozeTimeTick(),
+ this::triggerTimeUpdate);
}
@Override
@@ -4056,6 +4059,10 @@ public class KeyguardViewMediator implements CoreStartable,
mWallpaperSupportsAmbientMode = supportsAmbientMode;
}
+ private void triggerTimeUpdate(long timeInMillis) {
+ mUpdateMonitor.triggerTimeUpdate();
+ }
+
private static class StartKeyguardExitAnimParams {
@WindowManager.TransitionOldType int mTransit;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index af58d10f3066..df58b215167a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -20,6 +20,8 @@ package com.android.systemui.keyguard.domain.interactor
import android.annotation.SuppressLint
import android.util.Log
import com.android.app.tracing.coroutines.flow.filterTraced
+import com.android.app.tracing.coroutines.flow.shareInTraced
+import com.android.app.tracing.coroutines.flow.stateInTraced
import com.android.app.tracing.coroutines.flow.traceAs
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.coroutines.traceCoroutine
@@ -64,8 +66,6 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.shareIn
-import kotlinx.coroutines.flow.stateIn
/** Encapsulates business-logic related to the keyguard transitions. */
@SysUISingleton
@@ -102,12 +102,18 @@ constructor(
val transitions = repository.transitions
val transitionState: StateFlow<TransitionStep> =
- transitions.stateIn(scope, SharingStarted.Eagerly, TransitionStep())
+ transitions.stateInTraced(
+ "KTF-transitionState",
+ scope,
+ SharingStarted.Eagerly,
+ TransitionStep(),
+ )
private val sceneTransitionPair =
sceneInteractor.transitionState
.pairwise()
- .stateIn(
+ .stateInTraced(
+ "KTF-sceneTransitionPair",
scope,
SharingStarted.Eagerly,
WithPrev(
@@ -130,11 +136,16 @@ constructor(
repository.transitions
.pairwise()
.filter { it.newValue.transitionState == TransitionState.STARTED }
- .shareIn(scope, SharingStarted.Eagerly, replay = 1)
+ .shareInTraced(
+ "KTF-startedStepWithPrecedingStep",
+ scope,
+ SharingStarted.Eagerly,
+ replay = 1,
+ )
init {
// Collect non-canceled steps and emit transition values.
- scope.launch {
+ scope.launch("KTF-update-non-canceled") {
repository.transitions
.filter { it.transitionState != TransitionState.CANCELED }
.collect { step ->
@@ -145,7 +156,7 @@ constructor(
}
}
- scope.launch {
+ scope.launch("KTF-update-transitionMap") {
repository.transitions.collect {
// FROM->TO
transitionMap[Edge.create(it.from, it.to)]?.emit(it)
@@ -160,7 +171,7 @@ constructor(
// need to ensure we emit transitionValue(A) = 0f, since no further steps will be emitted
// where the from or to states are A. This would leave transitionValue(A) stuck at an
// arbitrary non-zero value.
- scope.launch {
+ scope.launch("KTF-update-canceled") {
startedStepWithPrecedingStep.collect { (prevStep, startedStep) ->
if (
prevStep.transitionState == TransitionState.CANCELED &&
@@ -180,7 +191,7 @@ constructor(
// Safety: When any transition is FINISHED, ensure all other transitionValue flows other
// than the FINISHED state are reset to a value of 0f. There have been rare but severe
// bugs that get the device stuck in a bad state when these are not properly reset.
- scope.launch {
+ scope.launch("KTF-update-finished") {
repository.transitions
.filter { it.transitionState == TransitionState.FINISHED }
.collect {
@@ -201,7 +212,7 @@ constructor(
* If the screen is turning off, finish the current transition immediately. Further
* frames won't be visible anyway.
*/
- scope.launch {
+ scope.launch("KTF-force-finish") {
powerInteractor.screenPowerState
.filter { it == ScreenPowerState.SCREEN_TURNING_OFF }
.collect { repository.forceFinishCurrentTransition() }
@@ -347,6 +358,7 @@ constructor(
}
}
}
+ .traceAs("KTF-transition-simulator")
/**
* This function is similar to flatMapLatest but it will additionally emit a FINISHED
@@ -372,7 +384,7 @@ constructor(
traceCoroutine("cancelAndJoin") { job?.cancelAndJoin() }
job =
- launch("inner") {
+ launch("KTF-flatMapLatestWithFinished") {
val innerFlow = transform(value)
try {
innerFlow.collect { step ->
@@ -398,7 +410,6 @@ constructor(
}
}
}
- .traceAs("flatMapLatestWithFinished")
/**
* Converts old KTF states to UNDEFINED when [SceneContainerFlag] is enabled.
@@ -451,7 +462,12 @@ constructor(
val startedKeyguardTransitionStep: StateFlow<TransitionStep> =
repository.transitions
.filter { step -> step.transitionState == TransitionState.STARTED }
- .stateIn(scope, SharingStarted.Eagerly, TransitionStep())
+ .stateInTraced(
+ "KTF-startedKeyguardTransitionStep",
+ scope,
+ SharingStarted.Eagerly,
+ TransitionStep(),
+ )
/**
* The [KeyguardState] we're currently in.
@@ -517,7 +533,7 @@ constructor(
it.from
}
}
- .stateIn(scope, SharingStarted.Eagerly, OFF)
+ .stateInTraced("KTF-currentKeyguardState", scope, SharingStarted.Eagerly, OFF)
val isInTransition =
combine(isInTransitionWhere({ true }, { true }), sceneInteractor.transitionState) {
@@ -629,7 +645,7 @@ constructor(
repository.transitions
.filter { it.transitionState == TransitionState.FINISHED }
.map { it.to }
- .stateIn(scope, SharingStarted.Eagerly, OFF)
+ .stateInTraced("KTF-finishedKeyguardState", scope, SharingStarted.Eagerly, OFF)
companion object {
private val TAG = KeyguardTransitionInteractor::class.simpleName
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/DismissibleHorizontalPager.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/DismissibleHorizontalPager.kt
deleted file mode 100644
index 8df916fe6969..000000000000
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/DismissibleHorizontalPager.kt
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.remedia.ui.compose
-
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationVector1D
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.pager.HorizontalPager
-import androidx.compose.foundation.pager.PagerScope
-import androidx.compose.foundation.pager.PagerState
-import androidx.compose.foundation.pager.rememberPagerState
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource
-import androidx.compose.ui.input.nestedscroll.nestedScroll
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.Velocity
-import androidx.compose.ui.unit.dp
-import com.android.compose.modifiers.thenIf
-import kotlinx.coroutines.launch
-
-/** State for a [DismissibleHorizontalPager] */
-class DismissibleHorizontalPagerState(
- val isDismissible: Boolean,
- val isScrollingEnabled: Boolean,
- val pagerState: PagerState,
- val offset: Animatable<Float, AnimationVector1D>,
-)
-
-/**
- * Returns a remembered [DismissibleHorizontalPagerState] that starts at [initialPage] and has
- * [pageCount] total pages.
- */
-@Composable
-fun rememberDismissibleHorizontalPagerState(
- isDismissible: Boolean = true,
- isScrollingEnabled: Boolean = true,
- initialPage: Int = 0,
- pageCount: () -> Int,
-): DismissibleHorizontalPagerState {
- val pagerState = rememberPagerState(initialPage = initialPage, pageCount = pageCount)
- val offset = remember { Animatable(0f) }
-
- return remember(isDismissible, isScrollingEnabled, pagerState, offset) {
- DismissibleHorizontalPagerState(
- isDismissible = isDismissible,
- isScrollingEnabled = isScrollingEnabled,
- pagerState = pagerState,
- offset = offset,
- )
- }
-}
-
-/**
- * A [HorizontalPager] that can be swiped-away to dismiss by the user when swiped farther left or
- * right once fully scrolled to the left-most or right-most page, respectively.
- */
-@Composable
-fun DismissibleHorizontalPager(
- state: DismissibleHorizontalPagerState,
- onDismissed: () -> Unit,
- modifier: Modifier = Modifier,
- key: ((Int) -> Any)? = null,
- pageSpacing: Dp = 0.dp,
- isFalseTouchDetected: Boolean,
- indicator: @Composable BoxScope.() -> Unit,
- pageContent: @Composable PagerScope.(page: Int) -> Unit,
-) {
- val scope = rememberCoroutineScope()
-
- val nestedScrollConnection = remember {
- object : NestedScrollConnection {
- override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
- return if (state.offset.value > 0f && available.x < 0f) {
- scope.launch { state.offset.snapTo(state.offset.value + available.x) }
- Offset(available.x, 0f)
- } else if (state.offset.value < 0f && available.x > 0f) {
- scope.launch { state.offset.snapTo(state.offset.value + available.x) }
- Offset(available.x, 0f)
- } else {
- Offset.Zero
- }
- }
-
- override fun onPostScroll(
- consumed: Offset,
- available: Offset,
- source: NestedScrollSource,
- ): Offset {
- return if (available.x > 0f) {
- scope.launch { state.offset.snapTo(state.offset.value + available.x) }
- Offset(available.x, 0f)
- } else if (available.x < 0f) {
- scope.launch { state.offset.snapTo(state.offset.value + available.x) }
- Offset(available.x, 0f)
- } else {
- Offset.Zero
- }
- }
-
- override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
- scope.launch {
- state.offset.animateTo(
- if (state.offset.value >= state.pagerState.layoutInfo.pageSize / 2f) {
- state.pagerState.layoutInfo.pageSize * 2f
- } else if (
- state.offset.value <= -state.pagerState.layoutInfo.pageSize / 2f
- ) {
- -state.pagerState.layoutInfo.pageSize * 2f
- } else {
- 0f
- }
- )
- if (state.offset.value != 0f) {
- onDismissed()
- }
- }
- return super.onPostFling(consumed, available)
- }
- }
- }
-
- Box(modifier = modifier) {
- HorizontalPager(
- state = state.pagerState,
- userScrollEnabled = state.isScrollingEnabled && !isFalseTouchDetected,
- key = key,
- pageSpacing = pageSpacing,
- pageContent = pageContent,
- modifier =
- Modifier.thenIf(state.isDismissible) {
- Modifier.nestedScroll(nestedScrollConnection).graphicsLayer {
- translationX = state.offset.value
- }
- },
- )
-
- indicator()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
index f07238895aa5..d6d185195c51 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
@@ -33,6 +33,7 @@ import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
+import androidx.compose.foundation.OverscrollEffect
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
@@ -54,6 +55,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ButtonDefaults
@@ -107,7 +110,9 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastCoerceIn
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed
import androidx.compose.ui.util.fastRoundToInt
@@ -120,6 +125,7 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState
import com.android.compose.animation.scene.transitions
+import com.android.compose.gesture.effect.rememberOffsetOverscrollEffect
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
@@ -137,7 +143,9 @@ import com.android.systemui.media.remedia.ui.viewmodel.MediaNavigationViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaOutputSwitcherChipViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaPlayPauseActionViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaSecondaryActionViewModel
+import com.android.systemui.media.remedia.ui.viewmodel.MediaSettingsButtonViewModel
import com.android.systemui.media.remedia.ui.viewmodel.MediaViewModel
+import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
@@ -208,43 +216,16 @@ private fun CardCarouselContent(
onDismissed: () -> Unit,
modifier: Modifier = Modifier,
) {
- val pagerState =
- rememberDismissibleHorizontalPagerState(
- isDismissible = behavior.isCarouselDismissible,
- isScrollingEnabled = behavior.isCarouselScrollingEnabled,
- ) {
- viewModel.cards.size
- }
+ val pagerState = rememberPagerState { viewModel.cards.size }
+ LaunchedEffect(pagerState.currentPage) { viewModel.onCardSelected(pagerState.currentPage) }
+
var isFalseTouchDetected: Boolean by
remember(behavior.isCarouselScrollFalseTouch) { mutableStateOf(false) }
+ val isSwipingEnabled = behavior.isCarouselScrollingEnabled && !isFalseTouchDetected
val roundedCornerShape = RoundedCornerShape(32.dp)
- LaunchedEffect(pagerState.pagerState.currentPage) {
- viewModel.onCardSelected(pagerState.pagerState.currentPage)
- }
-
- DismissibleHorizontalPager(
- state = pagerState,
- onDismissed = onDismissed,
- pageSpacing = 8.dp,
- key = { index -> viewModel.cards[index].key },
- indicator = {
- if (pagerState.pagerState.pageCount > 1) {
- PagerDots(
- pagerState = pagerState.pagerState,
- activeColor = Color(0xffdee0ff),
- nonActiveColor = Color(0xffa7a9ca),
- dotSize = 6.dp,
- spaceSize = 6.dp,
- modifier =
- Modifier.align(Alignment.BottomCenter).padding(8.dp).graphicsLayer {
- translationX = pagerState.offset.value
- },
- )
- }
- },
- isFalseTouchDetected = isFalseTouchDetected,
+ Box(
modifier =
modifier.padding(8.dp).clip(roundedCornerShape).pointerInput(behavior) {
if (behavior.isCarouselScrollFalseTouch != null) {
@@ -253,13 +234,54 @@ private fun CardCarouselContent(
isFalseTouchDetected = behavior.isCarouselScrollFalseTouch.invoke()
}
}
- },
- ) { index ->
- Card(
- viewModel = viewModel.cards[index],
- presentationStyle = presentationStyle,
- modifier = Modifier.clip(roundedCornerShape),
- )
+ }
+ ) {
+ @Composable
+ fun PagerContent(overscrollEffect: OverscrollEffect? = null) {
+ Box {
+ HorizontalPager(
+ state = pagerState,
+ userScrollEnabled = isSwipingEnabled,
+ pageSpacing = 8.dp,
+ key = { index: Int -> viewModel.cards[index].key },
+ overscrollEffect = overscrollEffect ?: rememberOffsetOverscrollEffect(),
+ ) { pageIndex: Int ->
+ Card(
+ viewModel = viewModel.cards[pageIndex],
+ presentationStyle = presentationStyle,
+ modifier = Modifier.clip(roundedCornerShape),
+ )
+ }
+
+ if (pagerState.pageCount > 1) {
+ PagerDots(
+ pagerState = pagerState,
+ activeColor = Color(0xffdee0ff),
+ nonActiveColor = Color(0xffa7a9ca),
+ dotSize = 6.dp,
+ spaceSize = 6.dp,
+ modifier = Modifier.align(Alignment.BottomCenter).padding(8.dp),
+ )
+ }
+ }
+ }
+
+ if (behavior.isCarouselDismissible) {
+ SwipeToDismiss(content = { PagerContent() }, onDismissed = onDismissed)
+ } else {
+ val overscrollEffect = rememberOffsetOverscrollEffect()
+ SwipeToReveal(
+ foregroundContent = { PagerContent(overscrollEffect) },
+ foregroundContentEffect = overscrollEffect,
+ revealedContent = { revealAmount ->
+ RevealedContent(
+ viewModel = viewModel.settingsButtonViewModel,
+ revealAmount = revealAmount,
+ )
+ },
+ isSwipingEnabled = isSwipingEnabled,
+ )
+ }
}
}
@@ -496,16 +518,19 @@ private fun ContentScope.CardForegroundContent(
modifier = Modifier.weight(1f).padding(end = 8.dp),
)
+ val playPauseSize = DpSize(width = 48.dp, height = 48.dp)
if (viewModel.actionButtonLayout == MediaCardActionButtonLayout.WithPlayPause) {
AnimatedVisibility(visible = viewModel.playPauseAction != null) {
PlayPauseAction(
viewModel = checkNotNull(viewModel.playPauseAction),
- buttonWidth = 48.dp,
+ buttonSize = playPauseSize,
buttonColor = colorScheme.primary,
iconColor = colorScheme.onPrimary,
buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 48.dp },
)
}
+ } else {
+ Spacer(Modifier.size(playPauseSize))
}
}
@@ -565,14 +590,19 @@ private fun ContentScope.CardForegroundContent(
}
}
- AnimatedVisibility(visible = viewModel.playPauseAction != null) {
- PlayPauseAction(
- viewModel = checkNotNull(viewModel.playPauseAction),
- buttonWidth = 48.dp,
- buttonColor = colorScheme.primary,
- iconColor = colorScheme.onPrimary,
- buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 48.dp },
- )
+ val playPauseSize = DpSize(width = 48.dp, height = 48.dp)
+ if (viewModel.actionButtonLayout == MediaCardActionButtonLayout.WithPlayPause) {
+ AnimatedVisibility(visible = viewModel.playPauseAction != null) {
+ PlayPauseAction(
+ viewModel = checkNotNull(viewModel.playPauseAction),
+ buttonSize = playPauseSize,
+ buttonColor = colorScheme.primary,
+ iconColor = colorScheme.onPrimary,
+ buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 48.dp },
+ )
+ }
+ } else {
+ Spacer(Modifier.size(playPauseSize))
}
}
}
@@ -628,7 +658,7 @@ private fun ContentScope.CompactCardForeground(
AnimatedVisibility(visible = viewModel.playPauseAction != null) {
PlayPauseAction(
viewModel = checkNotNull(viewModel.playPauseAction),
- buttonWidth = 72.dp,
+ buttonSize = DpSize(width = 72.dp, height = 48.dp),
buttonColor = MaterialTheme.colorScheme.primaryContainer,
iconColor = MaterialTheme.colorScheme.onPrimaryContainer,
buttonCornerRadius = { isPlaying -> if (isPlaying) 16.dp else 24.dp },
@@ -1084,7 +1114,7 @@ private fun OutputSwitcherChip(
@Composable
private fun ContentScope.PlayPauseAction(
viewModel: MediaPlayPauseActionViewModel,
- buttonWidth: Dp,
+ buttonSize: DpSize,
buttonColor: Color,
iconColor: Color,
buttonCornerRadius: (isPlaying: Boolean) -> Dp,
@@ -1102,7 +1132,7 @@ private fun ContentScope.PlayPauseAction(
enabled = viewModel.onClick != null,
colors = ButtonDefaults.buttonColors(containerColor = buttonColor),
shape = RoundedCornerShape(cornerRadius),
- modifier = Modifier.size(width = buttonWidth, height = 48.dp),
+ modifier = Modifier.size(buttonSize),
) {
when (viewModel.state) {
is MediaSessionState.Playing,
@@ -1186,6 +1216,65 @@ private fun SecondaryActionContent(
}
}
+/**
+ * Renders the revealed content on the sides of the horizontal pager.
+ *
+ * @param revealAmount A callback that can return the amount of revealing done. This value will be
+ * in a range slightly larger than `-1` to `+1` where `1` is fully revealed on the left-hand side,
+ * `-1` is fully revealed on the right-hand side, and `0` is not revealed at all. Numbers lower
+ * than `-1` or greater than `1` are possible when the overscroll effect adds additional pixels of
+ * offset.
+ */
+@Composable
+private fun RevealedContent(
+ viewModel: MediaSettingsButtonViewModel,
+ revealAmount: () -> Float,
+ modifier: Modifier = Modifier,
+) {
+ val horizontalPadding = 18.dp
+
+ // This custom layout's purpose is only to place the icon in the center of the revealed content,
+ // taking into account the amount of reveal.
+ Layout(
+ content = {
+ Icon(
+ icon = viewModel.icon,
+ modifier =
+ Modifier.size(48.dp)
+ .padding(12.dp)
+ .graphicsLayer {
+ alpha = abs(revealAmount()).fastCoerceIn(0f, 1f)
+ rotationZ = revealAmount() * 90
+ }
+ .clickable { viewModel.onClick() },
+ )
+ },
+ modifier = modifier,
+ ) { measurables, constraints ->
+ check(measurables.size == 1)
+ val placeable = measurables[0].measure(constraints)
+ val totalWidth =
+ min(horizontalPadding.roundToPx() * 2 + placeable.measuredWidth, constraints.maxWidth)
+
+ layout(totalWidth, constraints.maxHeight) {
+ coordinates?.size?.let { size ->
+ val reveal = revealAmount()
+ val x =
+ if (reveal >= 0f) {
+ ((size.width * abs(reveal)) - placeable.measuredWidth) / 2
+ } else {
+ size.width * (1 - abs(reveal) / 2) - placeable.measuredWidth / 2
+ }
+
+ placeable.place(
+ x = x.fastRoundToInt(),
+ y = (size.height - placeable.measuredHeight) / 2,
+ )
+ }
+ }
+ }
+}
+
/** Enumerates all supported media presentation styles. */
enum class MediaPresentationStyle {
/** The "normal" 3-row carousel look. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToDismiss.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToDismiss.kt
new file mode 100644
index 000000000000..b80bf4143252
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToDismiss.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.compose
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.foundation.OverscrollEffect
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.offset
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.Velocity
+import androidx.compose.ui.util.fastRoundToInt
+import kotlinx.coroutines.launch
+
+/** Swipe to dismiss that supports nested scrolling. */
+@Composable
+fun SwipeToDismiss(
+ content: @Composable (overscrollEffect: OverscrollEffect?) -> Unit,
+ onDismissed: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ val scope = rememberCoroutineScope()
+ val offsetAnimatable = remember { Animatable(0f) }
+
+ // This is the width of the revealed content UI box. It's not a state because it's not
+ // observed in any composition and is an object with a value to avoid the extra cost
+ // associated with boxing and unboxing an int.
+ val revealedContentBoxWidth = remember {
+ object {
+ var value = 0
+ }
+ }
+
+ val nestedScrollConnection = remember {
+ object : NestedScrollConnection {
+ override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+ return if (offsetAnimatable.value > 0f && available.x < 0f) {
+ scope.launch { offsetAnimatable.snapTo(offsetAnimatable.value + available.x) }
+ Offset(available.x, 0f)
+ } else if (offsetAnimatable.value < 0f && available.x > 0f) {
+ scope.launch { offsetAnimatable.snapTo(offsetAnimatable.value + available.x) }
+ Offset(available.x, 0f)
+ } else {
+ Offset.Zero
+ }
+ }
+
+ override fun onPostScroll(
+ consumed: Offset,
+ available: Offset,
+ source: NestedScrollSource,
+ ): Offset {
+ return if (available.x > 0f) {
+ scope.launch { offsetAnimatable.snapTo(offsetAnimatable.value + available.x) }
+ Offset(available.x, 0f)
+ } else if (available.x < 0f) {
+ scope.launch { offsetAnimatable.snapTo(offsetAnimatable.value + available.x) }
+ Offset(available.x, 0f)
+ } else {
+ Offset.Zero
+ }
+ }
+
+ override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
+ scope.launch {
+ offsetAnimatable.animateTo(
+ if (offsetAnimatable.value >= revealedContentBoxWidth.value / 2f) {
+ revealedContentBoxWidth.value * 2f
+ } else if (offsetAnimatable.value <= -revealedContentBoxWidth.value / 2f) {
+ -revealedContentBoxWidth.value * 2f
+ } else {
+ 0f
+ }
+ )
+ if (offsetAnimatable.value != 0f) {
+ onDismissed()
+ }
+ }
+ return super.onPostFling(consumed, available)
+ }
+ }
+ }
+
+ Box(
+ modifier =
+ modifier
+ .onSizeChanged { revealedContentBoxWidth.value = it.width }
+ .nestedScroll(nestedScrollConnection)
+ .offset { IntOffset(x = offsetAnimatable.value.fastRoundToInt(), y = 0) }
+ ) {
+ content(null)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToReveal.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToReveal.kt
new file mode 100644
index 000000000000..770762c7a29f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/SwipeToReveal.kt
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.compose
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.foundation.OverscrollEffect
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.absoluteOffset
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.overscroll
+import androidx.compose.foundation.withoutVisualEffect
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.pointer.PointerType
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.util.fastCoerceIn
+import androidx.compose.ui.util.fastRoundToInt
+import com.android.compose.gesture.NestedDraggable
+import com.android.compose.gesture.effect.OffsetOverscrollEffect
+import com.android.compose.gesture.effect.rememberOffsetOverscrollEffect
+import com.android.compose.gesture.nestedDraggable
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * Swipe to reveal that supports nested scrolling and an overscroll effect.
+ *
+ * @param foregroundContent The content to show above all else; this is the content that can be
+ * swiped sideways to reveal the [revealedContent]. This may contain a horizontally-scrollable
+ * component (for example a `HorizontalPager`).
+ * @param revealedContent The content that is shown below the [foregroundContent]; this is the
+ * content that can be revealed by swiping the [foregroundContent] sideways.
+ */
+@Composable
+fun SwipeToReveal(
+ foregroundContent: @Composable (overscrollEffect: OverscrollEffect?) -> Unit,
+ foregroundContentEffect: OffsetOverscrollEffect,
+ revealedContent: @Composable BoxScope.(revealAmount: () -> Float) -> Unit,
+ isSwipingEnabled: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ // This composable supports an overscroll effect, to make it possible for the user to
+ // "stretch" the UI when the side is fully revealed but the user keeps trying to reveal it
+ // further.
+ val revealedContentEffect = rememberOffsetOverscrollEffect()
+
+ // This is the width of the revealed content UI box. It's not a state because it's not
+ // observed in any composition and is an object with a value to avoid the extra cost
+ // associated with boxing and unboxing an int.
+ val revealedContentBoxWidth = remember {
+ object {
+ var value = 0
+ }
+ }
+
+ // In order to support the drag to reveal, infrastructure has to be put in place where a
+ // NestedDraggable helps by consuming the unconsumed drags and flings and applying the
+ // overscroll visual effect.
+ //
+ // This is the NestedDraggalbe controller.
+ val revealedContentDragController = rememberRevealedContentDragController {
+ revealedContentBoxWidth.value.toFloat()
+ }
+
+ Box(
+ modifier =
+ modifier
+ .nestedDraggable(
+ enabled = isSwipingEnabled,
+ draggable =
+ remember {
+ object : NestedDraggable {
+ override fun onDragStarted(
+ position: Offset,
+ sign: Float,
+ pointersDown: Int,
+ pointerType: PointerType?,
+ ): NestedDraggable.Controller {
+ return revealedContentDragController
+ }
+
+ override fun shouldConsumeNestedPostScroll(sign: Float): Boolean {
+ return revealedContentDragController.shouldConsumePostScrolls(
+ sign
+ )
+ }
+
+ override fun shouldConsumeNestedPreScroll(sign: Float): Boolean {
+ return revealedContentDragController.shouldConsumePreScrolls(
+ sign
+ )
+ }
+ }
+ },
+ orientation = Orientation.Horizontal,
+ overscrollEffect = revealedContentEffect.withoutVisualEffect(),
+ )
+ .overscroll(revealedContentEffect)
+ ) {
+ val density = LocalDensity.current
+
+ /**
+ * Returns the amount of visual offset, in pixels, that is comprised of both the offset from
+ * dragging and the overscroll effect's additional pixels after applying its animation curve
+ * on the raw distance.
+ */
+ fun offsetWithOverscroll(): Float {
+ return revealedContentDragController.offset +
+ OffsetOverscrollEffect.computeOffset(
+ density,
+ foregroundContentEffect.overscrollDistance,
+ ) +
+ OffsetOverscrollEffect.computeOffset(
+ density,
+ revealedContentEffect.overscrollDistance,
+ )
+ }
+
+ /**
+ * Returns the ratio of the amount by which the revealed content is revealed, where:
+ * - `0` means none of it is revealed
+ * - `+1` means all of it is revealed to the start of the foreground content
+ * - `-1` means all of it is revealed to the end of the foreground content
+ *
+ * The number could be smaller than `-1` or larger than `+1` to model overscrolling.
+ */
+ fun revealAmount(): Float {
+ return (offsetWithOverscroll() / revealedContentBoxWidth.value)
+ }
+
+ Layout(
+ content = { revealedContent { revealAmount() } },
+ modifier = Modifier.matchParentSize(),
+ ) { measurables, constraints ->
+ check(measurables.size == 1)
+ val placeable = measurables[0].measure(constraints.copy(minWidth = 0, minHeight = 0))
+ // Keep revealedContentBoxWidth up to date with the latest value.
+ revealedContentBoxWidth.value = placeable.measuredWidth
+
+ // Place the revealed content on the correct side, depending on the direction of the
+ // reveal.
+ val alignedToStart = revealAmount() >= 0f
+ layout(constraints.maxWidth, constraints.maxHeight) {
+ coordinates?.size?.let { size ->
+ placeable.place(
+ x = if (alignedToStart) 0 else size.width - placeable.measuredWidth,
+ y = 0,
+ )
+ }
+ }
+ }
+
+ Box(
+ modifier =
+ Modifier.absoluteOffset {
+ IntOffset(revealedContentDragController.offset.fastRoundToInt(), y = 0)
+ }
+ ) {
+ foregroundContent(foregroundContentEffect)
+ }
+ }
+}
+
+@Composable
+private fun rememberRevealedContentDragController(
+ maxBound: () -> Float
+): RevealedContentDragController {
+ val scope = rememberCoroutineScope()
+ return remember { RevealedContentDragController(scope = scope, maxBound = maxBound) }
+}
+
+private class RevealedContentDragController(
+ private val scope: CoroutineScope,
+ private val maxBound: () -> Float,
+) : NestedDraggable.Controller {
+ private val offsetAnimatable = Animatable(0f)
+ private var lastTarget = 0f
+ private var range = 0f..1f
+ private var shouldConsumePreScrolls by mutableStateOf(false)
+
+ override val autoStopNestedDrags: Boolean
+ get() = true
+
+ val offset: Float
+ get() = offsetAnimatable.value
+
+ fun shouldConsumePreScrolls(sign: Float): Boolean {
+ if (!shouldConsumePreScrolls) return false
+
+ if (lastTarget > 0f && sign < 0f) {
+ range = 0f..maxBound()
+ return true
+ }
+
+ if (lastTarget < 0f && sign > 0f) {
+ range = -maxBound()..0f
+ return true
+ }
+
+ return false
+ }
+
+ fun shouldConsumePostScrolls(sign: Float): Boolean {
+ val max = maxBound()
+ if (sign > 0f && lastTarget < max) {
+ range = 0f..maxBound()
+ return true
+ }
+
+ if (sign < 0f && lastTarget > -max) {
+ range = -maxBound()..0f
+ return true
+ }
+
+ return false
+ }
+
+ override fun onDrag(delta: Float): Float {
+ val previousTarget = lastTarget
+ lastTarget = (lastTarget + delta).fastCoerceIn(range.start, range.endInclusive)
+ val newTarget = lastTarget
+ scope.launch { offsetAnimatable.snapTo(newTarget) }
+ return lastTarget - previousTarget
+ }
+
+ override suspend fun onDragStopped(velocity: Float, awaitFling: suspend () -> Unit): Float {
+ val rangeMiddle = range.start + (range.endInclusive - range.start) / 2f
+ lastTarget =
+ when {
+ lastTarget >= rangeMiddle -> range.endInclusive
+ else -> range.start
+ }
+
+ shouldConsumePreScrolls = lastTarget != 0f
+ val newTarget = lastTarget
+
+ scope.launch { offsetAnimatable.animateTo(newTarget) }
+ return velocity
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSettingsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSettingsButtonViewModel.kt
new file mode 100644
index 000000000000..4f4c25c3c74f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaSettingsButtonViewModel.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.remedia.ui.viewmodel
+
+import com.android.systemui.common.shared.model.Icon
+
+data class MediaSettingsButtonViewModel(val icon: Icon.Resource, val onClick: () -> Unit)
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
index 19b08fa212db..a57da63a7a81 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/viewmodel/MediaViewModel.kt
@@ -252,6 +252,21 @@ constructor(
}
}
+ val settingsButtonViewModel =
+ MediaSettingsButtonViewModel(
+ icon =
+ Icon.Resource(
+ res = R.drawable.ic_settings,
+ contentDescription =
+ ContentDescription.Resource(res = R.string.controls_media_settings_button),
+ ),
+ onClick = {
+ falsingSystem.runIfNotFalseTap(FalsingManager.LOW_PENALTY) {
+ interactor.openMediaSettings()
+ }
+ },
+ )
+
/** Whether the carousel should be visible. */
val isCarouselVisible: Boolean
get() =
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 237ec7cfce7f..6cda192c4198 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -22,6 +22,7 @@ import static android.view.MotionEvent.TOOL_TYPE_FINGER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static com.android.systemui.Flags.edgebackGestureHandlerGetRunningTasksBackground;
+import static com.android.systemui.Flags.predictiveBackDelayWmTransition;
import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED;
@@ -1182,6 +1183,9 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
return;
} else if (dx > dy && dx > mTouchSlop) {
if (mAllowGesture) {
+ if (!predictiveBackDelayWmTransition() && mBackAnimation != null) {
+ mBackAnimation.onThresholdCrossed();
+ }
if (mBackAnimation == null) {
pilferPointers();
}
@@ -1197,7 +1201,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
// forward touch
mEdgeBackPlugin.onMotionEvent(ev);
dispatchToBackAnimation(ev);
- if (mBackAnimation != null && mThresholdCrossed && !mLastFrameThresholdCrossed) {
+ if (predictiveBackDelayWmTransition() && mBackAnimation != null
+ && mThresholdCrossed && !mLastFrameThresholdCrossed) {
mBackAnimation.onThresholdCrossed();
}
}
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 05a60a6db31e..b889c3e61837 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -18,6 +18,7 @@ package com.android.systemui.qs.composefragment
import android.annotation.SuppressLint
import android.content.Context
+import android.content.res.Configuration
import android.graphics.PointF
import android.graphics.Rect
import android.os.Bundle
@@ -35,6 +36,7 @@ import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.annotation.VisibleForTesting
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
+import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -48,6 +50,7 @@ import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -70,6 +73,8 @@ import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.layout.positionOnScreen
import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.CustomAccessibilityAction
@@ -102,6 +107,7 @@ import com.android.compose.theme.PlatformTheme
import com.android.mechanics.GestureContext
import com.android.systemui.Dumpable
import com.android.systemui.Flags
+import com.android.systemui.Flags.notificationShadeBlur
import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer
import com.android.systemui.brightness.ui.compose.ContainerColors
import com.android.systemui.compose.modifiers.sysuiResTag
@@ -251,7 +257,7 @@ constructor(
@Composable
private fun Content() {
- PlatformTheme {
+ PlatformTheme(isDarkTheme = if (notificationShadeBlur()) isSystemInDarkTheme() else true) {
ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) {
// TODO(b/389985793): Make sure that there is no coroutine work or recompositions
// happening when alwaysCompose is true but isQsVisibleAndAnyShadeExpanded is false.
@@ -746,19 +752,31 @@ constructor(
Box(
Modifier.systemGestureExclusionInShade(
enabled = {
- layoutState.transitionState is TransitionState.Idle
+ /*
+ * While we are transitioning into QS (either from QQS
+ * or from gone), the global position of the brightness
+ * slider will change in every frame. This causes
+ * the modifier to send a new gesture exclusion
+ * rectangle on every frame. Instead, only apply the
+ * modifier when this is settled.
+ */
+ layoutState.transitionState is TransitionState.Idle &&
+ viewModel.isNotTransitioning
}
)
) {
- BrightnessSliderContainer(
- viewModel = containerViewModel.brightnessSliderViewModel,
- containerColors =
- ContainerColors(
- Color.Transparent,
- ContainerColors.defaultContainerColor,
- ),
- modifier = Modifier.fillMaxWidth(),
- )
+ AlwaysDarkMode {
+ BrightnessSliderContainer(
+ viewModel =
+ containerViewModel.brightnessSliderViewModel,
+ containerColors =
+ ContainerColors(
+ Color.Transparent,
+ ContainerColors.defaultContainerColor,
+ ),
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
}
}
val TileGrid =
@@ -1236,3 +1254,31 @@ private fun interactionsConfig() =
private inline val alwaysCompose
get() = Flags.alwaysComposeQsUiFragment()
+
+/**
+ * Forces the configuration and themes to be dark theme. This is needed in order to have
+ * [colorResource] retrieve the dark mode colors.
+ *
+ * This should be removed when [notificationShadeBlur] is removed
+ */
+@Composable
+private fun AlwaysDarkMode(content: @Composable () -> Unit) {
+ if (notificationShadeBlur()) {
+ content()
+ } else {
+ val currentConfig = LocalConfiguration.current
+ val darkConfig =
+ Configuration(currentConfig).apply {
+ uiMode =
+ (uiMode and (Configuration.UI_MODE_NIGHT_MASK.inv())) or
+ Configuration.UI_MODE_NIGHT_YES
+ }
+ val newContext = LocalContext.current.createConfigurationContext(darkConfig)
+ CompositionLocalProvider(
+ LocalConfiguration provides darkConfig,
+ LocalContext provides newContext,
+ ) {
+ content()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index b61fa9cfe264..b7e9c5296bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -312,6 +312,11 @@ constructor(
source = containerViewModel.editModeViewModel.isEditing,
)
+ /** True if we are not in an expansion (from Gone to QQS/QS) animation. */
+ val isNotTransitioning by derivedStateOf {
+ viewTranslationY == 0f && viewAlpha == 1f && constrainedSquishinessFraction == 1f
+ }
+
private val inFirstPage: Boolean
get() = inFirstPageViewModel.inFirstPage
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
index 1cfc3d1f06be..f3ed07a8a753 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.compose
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -23,11 +24,13 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
+import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -65,6 +68,7 @@ fun TileDetails(modifier: Modifier = Modifier, detailsViewModel: DetailsViewMode
val title = tileDetailedViewModel.title
val subTitle = tileDetailedViewModel.subTitle
+ val colors = MaterialTheme.colorScheme
Column(
modifier =
@@ -72,20 +76,33 @@ fun TileDetails(modifier: Modifier = Modifier, detailsViewModel: DetailsViewMode
.fillMaxWidth()
// The height of the details view is TBD.
.fillMaxHeight()
+ .background(color = colors.onPrimary)
) {
CompositionLocalProvider(
value = LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant
) {
Row(
- modifier = Modifier.fillMaxWidth(),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ start = TileDetailsDefaults.TitleRowStart,
+ top = TileDetailsDefaults.TitleRowTop,
+ end = TileDetailsDefaults.TitleRowEnd,
+ bottom = TileDetailsDefaults.TitleRowBottom
+ ),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(
onClick = { detailsViewModel.closeDetailedView() },
+ colors = IconButtonDefaults.iconButtonColors(
+ contentColor = colors.onSurface
+ ),
modifier =
- Modifier.align(Alignment.CenterVertically)
+ Modifier
+ .align(Alignment.CenterVertically)
.height(TileDetailsDefaults.IconHeight)
+ .width(TileDetailsDefaults.IconWidth)
.padding(start = TileDetailsDefaults.IconPadding),
) {
Icon(
@@ -98,13 +115,19 @@ fun TileDetails(modifier: Modifier = Modifier, detailsViewModel: DetailsViewMode
text = title,
modifier = Modifier.align(Alignment.CenterVertically),
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.titleLarge,
+ style = MaterialTheme.typography.titleMedium,
+ color = colors.onSurface,
)
IconButton(
onClick = { tileDetailedViewModel.clickOnSettingsButton() },
+ colors = IconButtonDefaults.iconButtonColors(
+ contentColor = colors.onSurface
+ ),
modifier =
- Modifier.align(Alignment.CenterVertically)
+ Modifier
+ .align(Alignment.CenterVertically)
.height(TileDetailsDefaults.IconHeight)
+ .width(TileDetailsDefaults.IconWidth)
.padding(end = TileDetailsDefaults.IconPadding),
) {
Icon(
@@ -118,7 +141,8 @@ fun TileDetails(modifier: Modifier = Modifier, detailsViewModel: DetailsViewMode
text = subTitle,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.titleSmall,
+ style = MaterialTheme.typography.bodySmall,
+ color = colors.onSurfaceVariant,
)
}
MapTileDetailsContent(tileDetailedViewModel)
@@ -138,6 +162,11 @@ private fun MapTileDetailsContent(tileDetailsViewModel: TileDetailsViewModel) {
}
private object TileDetailsDefaults {
- val IconHeight = 48.dp
+ val IconHeight = 24.dp
+ val IconWidth = 24.dp
val IconPadding = 4.dp
+ val TitleRowStart = 14.dp
+ val TitleRowTop = 22.dp
+ val TitleRowEnd = 20.dp
+ val TitleRowBottom = 8.dp
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
index 3287443f0405..60ca6e6e67a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
@@ -23,11 +23,15 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
import javax.inject.Inject
@SysUISingleton
@Stable
-class DetailsViewModel @Inject constructor(val currentTilesInteractor: CurrentTilesInteractor) {
+class DetailsViewModel @Inject constructor(
+ val currentTilesInteractor: CurrentTilesInteractor,
+ val shadeModeInteractor: ShadeModeInteractor
+) {
/**
* The current active [TileDetailsViewModel]. If it's `null`, it means the qs overlay is not
@@ -52,6 +56,10 @@ class DetailsViewModel @Inject constructor(val currentTilesInteractor: CurrentTi
* @see activeTileDetails
*/
fun onTileClicked(spec: TileSpec?): Boolean {
+ if (!shadeModeInteractor.isDualShade){
+ return false
+ }
+
if (spec == null) {
_activeTileDetails.value = null
return false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index 2bacee12db8a..9940ae523b60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -16,12 +16,15 @@
package com.android.systemui.statusbar
+import android.annotation.SuppressLint
import android.app.ActivityManager
import android.content.res.Resources
+import android.os.Build
import android.os.SystemProperties
import android.os.Trace
import android.os.Trace.TRACE_TAG_APP
import android.util.IndentingPrintWriter
+import android.util.Log
import android.util.MathUtils
import android.view.CrossWindowBlurListeners
import android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED
@@ -45,7 +48,7 @@ open class BlurUtils @Inject constructor(
private val crossWindowBlurListeners: CrossWindowBlurListeners,
dumpManager: DumpManager
) : Dumpable {
- val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius).toFloat();
+ val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius).toFloat()
val maxBlurRadius = if (Flags.notificationShadeBlur()) {
blurConfig.maxBlurRadiusPx
} else {
@@ -55,6 +58,9 @@ open class BlurUtils @Inject constructor(
private var lastAppliedBlur = 0
private var earlyWakeupEnabled = false
+ /** When this is true, early wakeup flag is not reset on surface flinger when blur drops to 0 */
+ private var persistentEarlyWakeupRequired = false
+
init {
dumpManager.registerDumpable(this)
}
@@ -91,11 +97,8 @@ open class BlurUtils @Inject constructor(
return
}
if (lastAppliedBlur == 0 && radius != 0) {
- Trace.asyncTraceForTrackBegin(
- TRACE_TAG_APP, TRACK_NAME, "eEarlyWakeup (prepareBlur)", 0)
- earlyWakeupEnabled = true
createTransaction().use {
- it.setEarlyWakeupStart()
+ earlyWakeupStart(it, "eEarlyWakeup (prepareBlur)")
it.apply()
}
}
@@ -116,19 +119,15 @@ open class BlurUtils @Inject constructor(
if (shouldBlur(radius)) {
it.setBackgroundBlurRadius(viewRootImpl.surfaceControl, radius)
if (!earlyWakeupEnabled && lastAppliedBlur == 0 && radius != 0) {
- Trace.asyncTraceForTrackBegin(
- TRACE_TAG_APP,
- TRACK_NAME,
- "eEarlyWakeup (applyBlur)",
- 0
- )
- it.setEarlyWakeupStart()
- earlyWakeupEnabled = true
+ earlyWakeupStart(it, "eEarlyWakeup (applyBlur)")
}
- if (earlyWakeupEnabled && lastAppliedBlur != 0 && radius == 0) {
- it.setEarlyWakeupEnd()
- Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
- earlyWakeupEnabled = false
+ if (
+ earlyWakeupEnabled &&
+ lastAppliedBlur != 0 &&
+ radius == 0 &&
+ !persistentEarlyWakeupRequired
+ ) {
+ earlyWakeupEnd(it, "applyBlur")
}
lastAppliedBlur = radius
}
@@ -137,6 +136,26 @@ open class BlurUtils @Inject constructor(
}
}
+ private fun v(verboseLog: String) {
+ if (isLoggable) Log.v(TAG, verboseLog)
+ }
+
+ @SuppressLint("MissingPermission")
+ private fun earlyWakeupStart(transaction: SurfaceControl.Transaction, traceMethodName: String) {
+ v("earlyWakeupStart from $traceMethodName")
+ Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, traceMethodName, 0)
+ transaction.setEarlyWakeupStart()
+ earlyWakeupEnabled = true
+ }
+
+ @SuppressLint("MissingPermission")
+ private fun earlyWakeupEnd(transaction: SurfaceControl.Transaction, loggingContext: String) {
+ v("earlyWakeupEnd from $loggingContext")
+ transaction.setEarlyWakeupEnd()
+ Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
+ earlyWakeupEnabled = false
+ }
+
@VisibleForTesting
open fun createTransaction(): SurfaceControl.Transaction {
return SurfaceControl.Transaction()
@@ -177,7 +196,39 @@ open class BlurUtils @Inject constructor(
}
}
+ /**
+ * Enables/disables the early wakeup flag on surface flinger. Keeps the early wakeup flag on
+ * until it reset by passing false to this method.
+ */
+ fun setPersistentEarlyWakeup(persistentWakeup: Boolean, viewRootImpl: ViewRootImpl?) {
+ persistentEarlyWakeupRequired = persistentWakeup
+ if (viewRootImpl == null || !supportsBlursOnWindows()) return
+ if (persistentEarlyWakeupRequired) {
+ if (earlyWakeupEnabled) return
+ createTransaction().use {
+ earlyWakeupStart(it, "setEarlyWakeup")
+ it.apply()
+ }
+ } else {
+ if (!earlyWakeupEnabled) return
+ if (lastAppliedBlur > 0) {
+ Log.w(
+ TAG,
+ "resetEarlyWakeup invoked when lastAppliedBlur $lastAppliedBlur is " +
+ "non-zero, this means that the early wakeup signal was reset while blur" +
+ " was still active",
+ )
+ }
+ createTransaction().use {
+ earlyWakeupEnd(it, "resetEarlyWakeup")
+ it.apply()
+ }
+ }
+ }
+
companion object {
const val TRACK_NAME = "BlurUtils"
+ private const val TAG = "BlurUtils"
+ private val isLoggable = Log.isLoggable(TAG, Log.VERBOSE) || Build.isDebuggable()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
index 03c191e40ccf..2030606e4274 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
@@ -38,6 +38,7 @@ import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.ConversationLayout;
import com.android.internal.widget.ImageFloatingTextView;
+import com.android.systemui.statusbar.notification.icon.IconPack;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
@@ -61,10 +62,19 @@ public class NotificationGroupingUtil {
private static final VisibilityApplicator VISIBILITY_APPLICATOR = new VisibilityApplicator();
private static final VisibilityApplicator APP_NAME_APPLICATOR = new AppNameApplicator();
private static final ResultApplicator LEFT_ICON_APPLICATOR = new LeftIconApplicator();
- private static final DataExtractor ICON_EXTRACTOR = new DataExtractor() {
+
+ @VisibleForTesting
+ static final DataExtractor ICON_EXTRACTOR = new DataExtractor() {
@Override
public Object extractData(ExpandableNotificationRow row) {
- return row.getEntry().getSbn().getNotification();
+ if (NotificationBundleUi.isEnabled()) {
+ if (row.getEntryAdapter().getSbn() != null) {
+ return row.getEntryAdapter().getSbn().getNotification();
+ }
+ return null;
+ } else {
+ return row.getEntry().getSbn().getNotification();
+ }
}
};
@@ -253,7 +263,7 @@ public class NotificationGroupingUtil {
if (NotificationBundleUi.isEnabled()) {
sbn = row.getEntryAdapter() != null ? row.getEntryAdapter().getSbn() : null;
} else {
- sbn = row.getEntry().getSbn();
+ sbn = row.getEntryLegacy().getSbn();
}
return (sbn != null && sbn.getNotification().showsTime());
}
@@ -357,7 +367,8 @@ public class NotificationGroupingUtil {
boolean isEmpty(View view);
}
- private interface DataExtractor {
+ @VisibleForTesting
+ interface DataExtractor {
Object extractData(ExpandableNotificationRow row);
}
@@ -395,13 +406,17 @@ public class NotificationGroupingUtil {
}
}
- private abstract static class IconComparator implements ViewComparator {
+ @VisibleForTesting
+ static class IconComparator implements ViewComparator {
@Override
public boolean compare(View parent, View child, Object parentData, Object childData) {
return false;
}
protected boolean hasSameIcon(Object parentData, Object childData) {
+ if (parentData == null || childData == null) {
+ return false;
+ }
Icon parentIcon = ((Notification) parentData).getSmallIcon();
Icon childIcon = ((Notification) childData).getSmallIcon();
return parentIcon.sameAs(childIcon);
@@ -411,6 +426,10 @@ public class NotificationGroupingUtil {
* @return whether two ImageViews have the same colorFilterSet or none at all
*/
protected boolean hasSameColor(Object parentData, Object childData) {
+ if ((parentData == null && childData != null)
+ || (parentData != null && childData == null)) {
+ return false;
+ }
int parentColor = ((Notification) parentData).color;
int childColor = ((Notification) childData).color;
return parentColor == childColor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 472dc823423e..fce5a16bd85d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -265,7 +265,7 @@ constructor(
var blur = shadeRadius.toInt()
// If the blur comes from waking up, we don't want to zoom out the background
val zoomOut =
- if (shadeRadius != wakeAndUnlockBlurData.radius|| wakeAndUnlockBlurData.useZoom)
+ if (shadeRadius != wakeAndUnlockBlurData.radius || wakeAndUnlockBlurData.useZoom)
blurRadiusToZoomOut(blurRadius = shadeRadius)
else 0f
// Make blur be 0 if it is necessary to stop blur effect.
@@ -353,7 +353,9 @@ constructor(
interpolator = Interpolators.FAST_OUT_SLOW_IN
addUpdateListener { animation: ValueAnimator ->
wakeAndUnlockBlurData =
- WakeAndUnlockBlurData(blurUtils.blurRadiusOfRatio(animation.animatedValue as Float))
+ WakeAndUnlockBlurData(
+ blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
+ )
}
addListener(
object : AnimatorListenerAdapter() {
@@ -428,8 +430,10 @@ constructor(
applicationScope.launch {
wallpaperInteractor.wallpaperSupportsAmbientMode.collect { supported ->
wallpaperSupportsAmbientMode = supported
- if (getNewWakeBlurRadius(prevDozeAmount) == wakeAndUnlockBlurData.radius
- && !wakeAndUnlockBlurData.useZoom) {
+ if (
+ getNewWakeBlurRadius(prevDozeAmount) == wakeAndUnlockBlurData.radius &&
+ !wakeAndUnlockBlurData.useZoom
+ ) {
// Update wake and unlock radius only if the previous value comes from wake-up.
updateWakeBlurRadius(prevDozeAmount)
}
@@ -452,6 +456,21 @@ constructor(
scheduleUpdate()
}
}
+
+ applicationScope.launch {
+ windowRootViewBlurInteractor.isBlurCurrentlySupported.collect { supported ->
+ if (supported) {
+ // when battery saver changes, try scheduling an update.
+ scheduleUpdate()
+ } else {
+ // when blur becomes unsupported, no more updates will be scheduled,
+ // reset updateScheduled state.
+ updateScheduled = false
+ // reset blur and internal state to 0
+ onBlurApplied(0, 0.0f)
+ }
+ }
+ }
}
fun addListener(listener: DepthListener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 922afc7825c4..9cae6c135fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -329,6 +329,7 @@ constructor(
cookie,
component,
launchCujType = Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
+ returnCujType = Cuj.CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP,
) {
override suspend fun createController(
forLaunch: Boolean
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index 6ce350cb95f5..c862460ad6f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -194,6 +194,7 @@ constructor(
): OngoingActivityChipModel.Active {
return OngoingActivityChipModel.Active.Timer(
key = KEY,
+ isImportantForPrivacy = true,
icon =
OngoingActivityChipModel.ChipIcon.SingleColorIcon(
Icon.Resource(
@@ -232,6 +233,7 @@ constructor(
private fun createIconOnlyCastChip(deviceName: String?): OngoingActivityChipModel.Active {
return OngoingActivityChipModel.Active.IconOnly(
key = KEY,
+ isImportantForPrivacy = true,
icon =
OngoingActivityChipModel.ChipIcon.SingleColorIcon(
Icon.Resource(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index 1a802d634894..b303751b4d6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -115,22 +115,22 @@ constructor(
// If the user tapped this chip to show the HUN, we want to just show the icon because
// the HUN will show the rest of the information.
return OngoingActivityChipModel.Active.IconOnly(
- this.key,
- icon,
- colors,
- onClickListenerLegacy,
- clickBehavior,
+ key = this.key,
+ icon = icon,
+ colors = colors,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
if (this.promotedContent.shortCriticalText != null) {
return OngoingActivityChipModel.Active.Text(
- this.key,
- icon,
- colors,
- this.promotedContent.shortCriticalText,
- onClickListenerLegacy,
- clickBehavior,
+ key = this.key,
+ icon = icon,
+ colors = colors,
+ text = this.promotedContent.shortCriticalText,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
@@ -143,21 +143,21 @@ constructor(
// to always show "now". We don't want early testers to get that experience since it's
// not what will happen at launch, so just don't show any time.onometerstate
return OngoingActivityChipModel.Active.IconOnly(
- this.key,
- icon,
- colors,
- onClickListenerLegacy,
- clickBehavior,
+ key = this.key,
+ icon = icon,
+ colors = colors,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
if (this.promotedContent.time == null) {
return OngoingActivityChipModel.Active.IconOnly(
- this.key,
- icon,
- colors,
- onClickListenerLegacy,
- clickBehavior,
+ key = this.key,
+ icon = icon,
+ colors = colors,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
@@ -168,12 +168,12 @@ constructor(
systemClock.currentTimeMillis() + FUTURE_TIME_THRESHOLD_MILLIS
) {
OngoingActivityChipModel.Active.ShortTimeDelta(
- this.key,
- icon,
- colors,
+ key = this.key,
+ icon = icon,
+ colors = colors,
time = this.promotedContent.time.currentTimeMillis,
- onClickListenerLegacy,
- clickBehavior,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
} else {
// Don't show a `when` time that's close to now or in the past because it's
@@ -185,19 +185,19 @@ constructor(
// automatically handles this for us and we're hoping to launch the notification
// chips at the same time as the Compose chips.
return OngoingActivityChipModel.Active.IconOnly(
- this.key,
- icon,
- colors,
- onClickListenerLegacy,
- clickBehavior,
+ key = this.key,
+ icon = icon,
+ colors = colors,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
}
is PromotedNotificationContentModel.When.Chronometer -> {
return OngoingActivityChipModel.Active.Timer(
- this.key,
- icon,
- colors,
+ key = this.key,
+ icon = icon,
+ colors = colors,
startTimeMs = this.promotedContent.time.elapsedRealtimeMillis,
isEventInFuture = this.promotedContent.time.isCountDown,
onClickListenerLegacy = onClickListenerLegacy,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index 572c7faf19e6..fce428dcb7e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -94,9 +94,11 @@ constructor(
TAG,
LogLevel.INFO,
{},
- { "State: Recording(taskPackage=null) due to force-start" },
+ {
+ "State: Recording(hostPackage=null, taskPackage=null) due to force-start"
+ },
)
- ScreenRecordChipModel.Recording(recordedTask = null)
+ ScreenRecordChipModel.Recording(hostPackage = null, recordedTask = null)
} else {
when (screenRecordState) {
is ScreenRecordModel.DoingNothing -> {
@@ -124,13 +126,25 @@ constructor(
} else {
null
}
+ val hostPackage =
+ if (mediaProjectionState is MediaProjectionState.Projecting) {
+ mediaProjectionState.hostPackage
+ } else {
+ null
+ }
logger.log(
TAG,
LogLevel.INFO,
- { str1 = recordedTask?.baseIntent?.component?.packageName },
- { "State: Recording(taskPackage=$str1)" },
+ {
+ str1 = hostPackage
+ str2 = recordedTask?.baseIntent?.component?.packageName
+ },
+ { "State: Recording(hostPackage=$str1, taskPackage=$str2)" },
+ )
+ ScreenRecordChipModel.Recording(
+ hostPackage = hostPackage,
+ recordedTask = recordedTask,
)
- ScreenRecordChipModel.Recording(recordedTask)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/model/ScreenRecordChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/model/ScreenRecordChipModel.kt
index ba6cd4df8d47..0a7278792e70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/model/ScreenRecordChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/model/ScreenRecordChipModel.kt
@@ -29,10 +29,13 @@ sealed interface ScreenRecordChipModel {
/**
* There's an active screen recording happening.
*
+ * @property hostPackage the package name of the app that is receiving the content of the media
+ * projection (aka which app the phone screen contents are being sent to).
* @property recordedTask the task being recorded if the user is recording only a single app.
* Null if the user is recording the entire screen or we don't have the task info yet.
*/
data class Recording(
+ val hostPackage: String?,
val recordedTask: ActivityManager.RunningTaskInfo?,
) : ScreenRecordChipModel
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index 55c89a96422f..363b8beab2d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -77,6 +77,7 @@ constructor(
is ScreenRecordChipModel.Starting -> {
OngoingActivityChipModel.Active.Countdown(
key = KEY,
+ isImportantForPrivacy = true,
colors = ColorsModel.Red,
secondsUntilStarted = state.millisUntilStarted.toCountdownSeconds(),
)
@@ -84,6 +85,7 @@ constructor(
is ScreenRecordChipModel.Recording -> {
OngoingActivityChipModel.Active.Timer(
key = KEY,
+ isImportantForPrivacy = true,
icon =
OngoingActivityChipModel.ChipIcon.SingleColorIcon(
Icon.Resource(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index 92e17bdd511a..0defa531d18d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -222,6 +222,7 @@ constructor(
): OngoingActivityChipModel.Active {
return OngoingActivityChipModel.Active.Timer(
key = KEY,
+ isImportantForPrivacy = true,
icon =
OngoingActivityChipModel.ChipIcon.SingleColorIcon(
Icon.Resource(
@@ -257,6 +258,7 @@ constructor(
private fun createIconOnlyShareToAppChip(): OngoingActivityChipModel.Active {
return OngoingActivityChipModel.Active.IconOnly(
key = KEY,
+ isImportantForPrivacy = true,
icon =
OngoingActivityChipModel.ChipIcon.SingleColorIcon(
Icon.Resource(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index b94e7b249233..104c2b546200 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -107,11 +107,15 @@ fun OngoingActivityChip(
}
}
.thenIf(isClickable) { Modifier.widthIn(min = minWidth) }
- .layout { measurable, constraints ->
- val placeable = measurable.measure(constraints)
- layout(placeable.width, placeable.height) {
- if (constraints.maxWidth >= minWidth.roundToPx()) {
- placeable.place(0, 0)
+ // For non-privacy-related chips, only show the chip if there's enough space for at
+ // least the minimum width.
+ .thenIf(!model.isImportantForPrivacy) {
+ Modifier.layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+ layout(placeable.width, placeable.height) {
+ if (constraints.maxWidth >= minWidth.roundToPx()) {
+ placeable.place(0, 0)
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index 364e6656ee9d..e28f3684b0fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -57,6 +57,11 @@ sealed class OngoingActivityChipModel {
* A key that uniquely identifies this chip. Used for better visual effects, like animation.
*/
open val key: String,
+ /**
+ * True if this chip is critical for privacy so we should keep it visible at all times, and
+ * false otherwise.
+ */
+ open val isImportantForPrivacy: Boolean = false,
/** The icon to show on the chip. If null, no icon will be shown. */
open val icon: ChipIcon?,
/** What colors to use for the chip. */
@@ -81,6 +86,7 @@ sealed class OngoingActivityChipModel {
/** This chip shows only an icon and nothing else. */
data class IconOnly(
override val key: String,
+ override val isImportantForPrivacy: Boolean = false,
override val icon: ChipIcon,
override val colors: ColorsModel,
override val onClickListenerLegacy: View.OnClickListener?,
@@ -91,6 +97,7 @@ sealed class OngoingActivityChipModel {
) :
Active(
key,
+ isImportantForPrivacy,
icon,
colors,
onClickListenerLegacy,
@@ -105,6 +112,7 @@ sealed class OngoingActivityChipModel {
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
override val key: String,
+ override val isImportantForPrivacy: Boolean = false,
override val icon: ChipIcon,
override val colors: ColorsModel,
/**
@@ -138,6 +146,7 @@ sealed class OngoingActivityChipModel {
) :
Active(
key,
+ isImportantForPrivacy,
icon,
colors,
onClickListenerLegacy,
@@ -155,6 +164,7 @@ sealed class OngoingActivityChipModel {
*/
data class ShortTimeDelta(
override val key: String,
+ override val isImportantForPrivacy: Boolean = false,
override val icon: ChipIcon,
override val colors: ColorsModel,
/**
@@ -175,6 +185,7 @@ sealed class OngoingActivityChipModel {
) :
Active(
key,
+ isImportantForPrivacy,
icon,
colors,
onClickListenerLegacy,
@@ -196,6 +207,7 @@ sealed class OngoingActivityChipModel {
*/
data class Countdown(
override val key: String,
+ override val isImportantForPrivacy: Boolean = false,
override val colors: ColorsModel,
/** The number of seconds until an event is started. */
val secondsUntilStarted: Long,
@@ -205,6 +217,7 @@ sealed class OngoingActivityChipModel {
) :
Active(
key,
+ isImportantForPrivacy,
icon = null,
colors,
onClickListenerLegacy = null,
@@ -219,6 +232,7 @@ sealed class OngoingActivityChipModel {
/** This chip shows the specified [text] in the chip. */
data class Text(
override val key: String,
+ override val isImportantForPrivacy: Boolean = false,
override val icon: ChipIcon,
override val colors: ColorsModel,
// TODO(b/361346412): Enforce a max length requirement?
@@ -231,6 +245,7 @@ sealed class OngoingActivityChipModel {
) :
Active(
key,
+ isImportantForPrivacy,
icon,
colors,
onClickListenerLegacy,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
index 8228b5533fca..76d2af86e239 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
@@ -265,11 +265,12 @@ constructor(
// [shouldSquish] returns false for that model, but protect against it just in case.)
val currentIcon = icon ?: return this
return OngoingActivityChipModel.Active.IconOnly(
- key,
- currentIcon,
- colors,
- onClickListenerLegacy,
- clickBehavior,
+ key = key,
+ isImportantForPrivacy = isImportantForPrivacy,
+ icon = currentIcon,
+ colors = colors,
+ onClickListenerLegacy = onClickListenerLegacy,
+ clickBehavior = clickBehavior,
)
}
@@ -374,6 +375,9 @@ constructor(
* Sort the given chip [bundle] in order of priority, and divide the chips between active,
* overflow, and inactive (see [MultipleOngoingActivityChipsModel] for a description of each).
*/
+ // IMPORTANT: PromotedNotificationsInteractor re-implements this same ordering scheme. Any
+ // changes here should also be made in PromotedNotificationsInteractor.
+ // TODO(b/402471288): Create a single source of truth for the ordering.
private fun rankChips(bundle: ChipBundle): MultipleOngoingActivityChipsModel {
val activeChips = mutableListOf<OngoingActivityChipModel.Active>()
val overflowChips = mutableListOf<OngoingActivityChipModel.Active>()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
index 7964950a2917..499e3ae2fa5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
@@ -16,10 +16,10 @@
package com.android.systemui.statusbar.core
+import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
import com.android.systemui.statusbar.phone.AutoHideControllerStore
@@ -40,7 +40,7 @@ constructor(
private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
private val initializerStore: StatusBarInitializerStore,
private val autoHideControllerStore: AutoHideControllerStore,
- private val displayScopeRepository: DisplayScopeRepository,
+ private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
private val statusBarWindowStateRepositoryStore: StatusBarWindowStateRepositoryStore,
) :
StatusBarPerDisplayStoreImpl<StatusBarOrchestrator>(
@@ -59,10 +59,10 @@ constructor(
val statusBarWindowController =
statusBarWindowControllerStore.forDisplay(displayId) ?: return null
val autoHideController = autoHideControllerStore.forDisplay(displayId) ?: return null
+ val displayScope = displayScopeRepository[displayId] ?: return null
return factory.create(
displayId,
- // TODO: b/398825844 - Handle nullness to prevent leaking CoroutineScope.
- displayScopeRepository.scopeForDisplay(displayId),
+ displayScope,
statusBarWindowStateRepositoryStore.forDisplay(displayId),
statusBarModeRepository,
statusBarInitializer,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index 3c0d6c3b8df3..b257c2bfc29a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -16,11 +16,11 @@
package com.android.systemui.statusbar.data.repository
+import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.display.data.repository.PerDisplayStore
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.LightBarControllerImpl
@@ -41,7 +41,7 @@ constructor(
@Background backgroundApplicationScope: CoroutineScope,
displayRepository: DisplayRepository,
private val factory: LightBarControllerImpl.Factory,
- private val displayScopeRepository: DisplayScopeRepository,
+ private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
private val darkIconDispatcherStore: DarkIconDispatcherStore,
) :
@@ -55,13 +55,9 @@ constructor(
val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
val statusBarModePerDisplayRepository =
statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
+ val displayScope = displayScopeRepository[displayId] ?: return null
return factory
- .create(
- displayId,
- displayScopeRepository.scopeForDisplay(displayId),
- darkIconDispatcher,
- statusBarModePerDisplayRepository,
- )
+ .create(displayId, displayScope, darkIconDispatcher, statusBarModePerDisplayRepository)
.also { it.start() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
index 32dc8407ac90..f3c68553abfd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
@@ -16,11 +16,11 @@
package com.android.systemui.statusbar.data.repository
+import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.display.data.repository.PerDisplayStore
import com.android.systemui.display.data.repository.SingleDisplayStore
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -44,7 +44,7 @@ constructor(
@Background backgroundApplicationScope: CoroutineScope,
displayRepository: DisplayRepository,
private val factory: PrivacyDotViewControllerImpl.Factory,
- private val displayScopeRepository: DisplayScopeRepository,
+ private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
private val contentInsetsProviderStore: StatusBarContentInsetsProviderStore,
) :
@@ -58,11 +58,8 @@ constructor(
val configurationController =
statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
val contentInsetsProvider = contentInsetsProviderStore.forDisplay(displayId) ?: return null
- return factory.create(
- displayScopeRepository.scopeForDisplay(displayId),
- configurationController,
- contentInsetsProvider,
- )
+ val displayScope = displayScopeRepository[displayId] ?: return null
+ return factory.create(displayScope, configurationController, contentInsetsProvider)
}
override suspend fun onDisplayRemovalAction(instance: PrivacyDotViewController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 3bb1ff161b6f..fed9417edd88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -81,7 +81,6 @@ public final class NotificationClicker implements View.OnClickListener {
mPowerInteractor.wakeUpIfDozing("NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- final NotificationEntry entry = row.getEntry();
mLogger.logOnClick(row.getLoggingKey());
// Check if the notification is displaying the menu, if so slide notification back
@@ -109,16 +108,16 @@ public final class NotificationClicker implements View.OnClickListener {
DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
if (NotificationBundleUi.isEnabled()) {
- if (!row.getEntryAdapter().isBubbleCapable() && mBubblesOptional.isPresent()) {
+ if (!row.getEntryAdapter().isBubble() && mBubblesOptional.isPresent()) {
mBubblesOptional.get().collapseStack();
}
+ row.getEntryAdapter().onEntryClicked(row);
} else {
if (!row.getEntryLegacy().isBubble() && mBubblesOptional.isPresent()) {
mBubblesOptional.get().collapseStack();
}
+ mNotificationActivityStarter.onNotificationClicked(row.getEntryLegacy(), row);
}
-
- mNotificationActivityStarter.onNotificationClicked(entry, row);
}
private boolean isMenuVisible(ExpandableNotificationRow row) {
@@ -129,9 +128,12 @@ public final class NotificationClicker implements View.OnClickListener {
* Attaches the click listener to the row if appropriate.
*/
public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
+ boolean isBubble = NotificationBundleUi.isEnabled()
+ ? row.getEntryAdapter().isBubble()
+ : row.getEntryLegacy().isBubble();
Notification notification = sbn.getNotification();
if (notification.contentIntent != null || notification.fullScreenIntent != null
- || row.getEntry().isBubble()) {
+ || isBubble) {
if (NotificationBundleUi.isEnabled()) {
row.setBubbleClickListener(
v -> row.getEntryAdapter().onNotificationBubbleIconClicked());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
index d06f24fdb81b..ba4001014681 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
@@ -17,3 +17,4 @@ valiiftime@google.com
yurilin@google.com
per-file MediaNotificationProcessor.java = ethibodeau@google.com
+per-file MagicActionBackgroundDrawable.kt = dupin@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
index f6535730cf77..8fc6cbe7c9e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
@@ -69,10 +69,13 @@ public class BundleEntry extends PipelineEntry {
return mUnmodifiableChildren;
}
+ void clearChildren() {
+ mChildren.clear();
+ }
+
/**
* @return Null because bundles do not have an associated NotificationEntry.
*/
-
@Nullable
@Override
public NotificationEntry getRepresentativeEntry() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
index e743d87a784c..be17ae56c315 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
@@ -98,7 +98,7 @@ class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter {
return false
}
- override fun isBubbleCapable(): Boolean {
+ override fun isBubble(): Boolean {
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
index f39bd0324995..3757ebfb9986 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
@@ -125,7 +125,7 @@ public interface EntryAdapter {
boolean canDragAndDrop();
- boolean isBubbleCapable();
+ boolean isBubble();
@Nullable String getStyle();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
index 12cfa91d9890..a23c5a3ea9f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
@@ -121,7 +121,7 @@ class NotificationEntryAdapter(
return false
}
- override fun isBubbleCapable(): Boolean {
+ override fun isBubble(): Boolean {
return entry.isBubble
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 5cea82140692..fe2bd345d559 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -567,7 +567,7 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
for (BundleEntry be : mIdToBundleEntry.values()) {
be.beginNewAttachState();
- // TODO(b/399736937) Clear bundle children
+ be.clearChildren();
// BundleEntry has not representative summary so we do not need to clear it here.
}
mNotifList.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
index afba85b49c30..c8ec85d0a227 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
@@ -24,10 +24,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.statusbar.notification.collection.ListEntry;
-import com.android.systemui.statusbar.notification.collection.PipelineEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.PipelineEntry;
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
@@ -100,7 +99,7 @@ public class ColorizedFgsCoordinator implements Coordinator {
public boolean isInSection(PipelineEntry entry) {
NotificationEntry notificationEntry = entry.getRepresentativeEntry();
if (notificationEntry != null) {
- return isRichOngoing(notificationEntry);
+ return isRichOngoing(notificationEntry) || isPromotedNotifChip(notificationEntry);
}
return false;
}
@@ -159,4 +158,10 @@ public class ColorizedFgsCoordinator implements Coordinator {
return entry.getImportance() > IMPORTANCE_MIN
&& notification.isStyle(Notification.CallStyle.class);
}
+
+ private boolean isPromotedNotifChip(NotificationEntry entry) {
+ return PromotedNotificationUi.isEnabled()
+ && entry.getImportance() > IMPORTANCE_MIN
+ && mOrderedPromotedNotifKeys.contains(entry.getKey());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
index 2f0701f96f28..3747aba3a109 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.util.ArrayMap
+import com.android.systemui.statusbar.notification.collection.BundleEntry
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.PipelineEntry
import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -37,9 +38,17 @@ class GroupCountCoordinator @Inject constructor() : Coordinator {
private fun onBeforeFinalizeFilter(entries: List<PipelineEntry>) {
// save untruncated child counts to our internal map
untruncatedChildCounts.clear()
- entries.asSequence().filterIsInstance<GroupEntry>().forEach { groupEntry ->
- untruncatedChildCounts[groupEntry] = groupEntry.children.size
- }
+ entries.asSequence()
+ .flatMap { entry ->
+ when (entry) {
+ is GroupEntry -> listOf(entry)
+ is BundleEntry -> entry.children.filterIsInstance<GroupEntry>()
+ else -> emptyList()
+ }
+ }
+ .forEach { groupEntry ->
+ untruncatedChildCounts[groupEntry] = groupEntry.children.size
+ }
}
private fun onAfterRenderGroup(group: GroupEntry, controller: NotifGroupController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index 1be415d7bf47..20169ef481bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -36,6 +36,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.statusbar.notification.collection.BundleEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.PipelineEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -307,8 +308,15 @@ public class PreparationCoordinator implements Coordinator {
private void inflateAllRequiredViews(List<PipelineEntry> entries) {
for (int i = 0, size = entries.size(); i < size; i++) {
PipelineEntry entry = entries.get(i);
- if (NotificationBundleUi.isEnabled() && entry instanceof BundleEntry) {
- // TODO(b/399738511) Inflate bundle views.
+ if (NotificationBundleUi.isEnabled() && entry instanceof BundleEntry bundleEntry) {
+ for (ListEntry listEntry : bundleEntry.getChildren()) {
+ if (listEntry instanceof GroupEntry groupEntry) {
+ inflateRequiredGroupViews(groupEntry);
+ } else {
+ NotificationEntry notifEntry = (NotificationEntry) listEntry;
+ inflateRequiredNotifViews(notifEntry);
+ }
+ }
} else if (entry instanceof GroupEntry) {
GroupEntry groupEntry = (GroupEntry) entry;
inflateRequiredGroupViews(groupEntry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index adc049e7cdf1..2f9d86b45d1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -20,6 +20,7 @@ import android.app.Notification.CallStyle.CALL_TYPE_ONGOING
import android.app.Notification.CallStyle.CALL_TYPE_SCREENING
import android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN
import android.app.Notification.EXTRA_CALL_TYPE
+import android.app.Notification.FLAG_ONGOING_EVENT
import android.app.PendingIntent
import android.content.Context
import android.graphics.drawable.Icon
@@ -29,8 +30,8 @@ import com.android.app.tracing.traceSection
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.GroupEntry
-import com.android.systemui.statusbar.notification.collection.PipelineEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.PipelineEntry
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
@@ -149,6 +150,8 @@ private class ActiveNotificationsStoreBuilder(
key = key,
groupKey = sbn.groupKey,
whenTime = sbn.notification.`when`,
+ isForegroundService = sbn.notification.isForegroundService,
+ isOngoingEvent = (sbn.notification.flags and FLAG_ONGOING_EVENT) != 0,
isAmbient = sectionStyleProvider.isMinimized(this),
isRowDismissed = isRowDismissed,
isSilent = sectionStyleProvider.isSilent(this),
@@ -176,6 +179,8 @@ private fun ActiveNotificationsStore.createOrReuse(
key: String,
groupKey: String?,
whenTime: Long,
+ isForegroundService: Boolean,
+ isOngoingEvent: Boolean,
isAmbient: Boolean,
isRowDismissed: Boolean,
isSilent: Boolean,
@@ -201,6 +206,8 @@ private fun ActiveNotificationsStore.createOrReuse(
key = key,
groupKey = groupKey,
whenTime = whenTime,
+ isForegroundService = isForegroundService,
+ isOngoingEvent = isOngoingEvent,
isAmbient = isAmbient,
isRowDismissed = isRowDismissed,
isSilent = isSilent,
@@ -226,6 +233,8 @@ private fun ActiveNotificationsStore.createOrReuse(
key = key,
groupKey = groupKey,
whenTime = whenTime,
+ isForegroundService = isForegroundService,
+ isOngoingEvent = isOngoingEvent,
isAmbient = isAmbient,
isRowDismissed = isRowDismissed,
isSilent = isSilent,
@@ -252,6 +261,8 @@ private fun ActiveNotificationModel.isCurrent(
key: String,
groupKey: String?,
whenTime: Long,
+ isForegroundService: Boolean,
+ isOngoingEvent: Boolean,
isAmbient: Boolean,
isRowDismissed: Boolean,
isSilent: Boolean,
@@ -276,6 +287,8 @@ private fun ActiveNotificationModel.isCurrent(
key != this.key -> false
groupKey != this.groupKey -> false
whenTime != this.whenTime -> false
+ isForegroundService != this.isForegroundService -> false
+ isOngoingEvent != this.isOngoingEvent -> false
isAmbient != this.isAmbient -> false
isRowDismissed != this.isRowDismissed -> false
isSilent != this.isSilent -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 7e19ff115a92..27b2788f0b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -199,16 +199,18 @@ constructor(
extras?.getBoolean(EXTRA_PROGRESS_INDETERMINATE)
private fun Notification.extractWhen(): When? {
+ val whenTime = getWhen()
+
return when {
showsChronometer() -> {
When.Chronometer(
elapsedRealtimeMillis =
- `when` + systemClock.elapsedRealtime() - systemClock.currentTimeMillis(),
+ whenTime + systemClock.elapsedRealtime() - systemClock.currentTimeMillis(),
isCountDown = chronometerCountDown(),
)
}
- showsTime() -> When.Time(currentTimeMillis = `when`)
+ showsTime() -> When.Time(currentTimeMillis = whenTime)
else -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
index a99ca072b6c8..96d41f1b3aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractor.kt
@@ -19,7 +19,11 @@ package com.android.systemui.statusbar.notification.promoted.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor
+import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style.Ineligible
@@ -27,9 +31,12 @@ import com.android.systemui.statusbar.notification.shared.ActiveNotificationMode
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
@@ -38,39 +45,156 @@ import kotlinx.coroutines.flow.map
* presented order of current notification status bar chips.
*/
@SysUISingleton
+@OptIn(ExperimentalCoroutinesApi::class)
class PromotedNotificationsInteractor
@Inject
constructor(
- activeNotificationsInteractor: ActiveNotificationsInteractor,
+ private val activeNotificationsInteractor: ActiveNotificationsInteractor,
+ screenRecordChipInteractor: ScreenRecordChipInteractor,
+ mediaProjectionChipInteractor: MediaProjectionChipInteractor,
callChipInteractor: CallChipInteractor,
notifChipsInteractor: StatusBarNotificationChipsInteractor,
@Background backgroundDispatcher: CoroutineDispatcher,
) {
+ private val screenRecordChipNotification: Flow<NotifAndPromotedContent?> =
+ screenRecordChipInteractor.screenRecordState.flatMapLatest { screenRecordModel ->
+ when (screenRecordModel) {
+ is ScreenRecordChipModel.DoingNothing -> flowOf(null)
+ is ScreenRecordChipModel.Starting -> flowOf(null)
+ is ScreenRecordChipModel.Recording ->
+ createRecordingNotificationFlow(hostPackage = screenRecordModel.hostPackage)
+ }
+ }
+
+ private val mediaProjectionChipNotification: Flow<NotifAndPromotedContent?> =
+ mediaProjectionChipInteractor.projection.flatMapLatest { projectionModel ->
+ when (projectionModel) {
+ is ProjectionChipModel.NotProjecting -> flowOf(null)
+ is ProjectionChipModel.Projecting ->
+ createRecordingNotificationFlow(
+ hostPackage = projectionModel.projectionState.hostPackage
+ )
+ }
+ }
+
+ /**
+ * Creates a flow emitting the screen-recording-related notification corresponding to the given
+ * package name (if we can find it).
+ *
+ * @param hostPackage the package name of the app that is receiving the content of the media
+ * projection (aka which app the phone screen contents are being sent to).
+ */
+ private fun createRecordingNotificationFlow(
+ hostPackage: String?
+ ): Flow<NotifAndPromotedContent?> =
+ if (hostPackage == null) {
+ flowOf(null)
+ } else {
+ activeNotificationsInteractor.allRepresentativeNotifications
+ .map { allNotifs ->
+ findBestMatchingMediaProjectionNotif(allNotifs.values, hostPackage)
+ }
+ .distinctUntilChanged()
+ }
+
+ /**
+ * Finds the best notification that matches the given [hostPackage] that looks like a recording
+ * notification, or null if we couldn't find a uniquely good match.
+ */
+ private fun findBestMatchingMediaProjectionNotif(
+ allNotifs: Collection<ActiveNotificationModel>,
+ hostPackage: String,
+ ): NotifAndPromotedContent? {
+ val candidates = allNotifs.filter { it.packageName == hostPackage }
+ if (candidates.isEmpty()) {
+ return null
+ }
+
+ candidates
+ .findOnlyOrNull { it.isForegroundService }
+ ?.let {
+ return it.toNotifAndPromotedContent()
+ }
+ candidates
+ .findOnlyOrNull { it.isOngoingEvent }
+ ?.let {
+ return it.toNotifAndPromotedContent()
+ }
+ candidates
+ .findOnlyOrNull { it.isForegroundService && it.isOngoingEvent }
+ ?.let {
+ return it.toNotifAndPromotedContent()
+ }
+ // We weren't able to find exactly 1 match for the given [hostPackage], so just don't match
+ // at all.
+ return null
+ }
+
+ /**
+ * Returns the single notification matching the given [predicate] if there's only 1 match, or
+ * null if there's 0 or 2+ matches.
+ */
+ private fun List<ActiveNotificationModel>.findOnlyOrNull(
+ predicate: (ActiveNotificationModel) -> Boolean
+ ): ActiveNotificationModel? {
+ val list = this.filter(predicate)
+ return if (list.size == 1) {
+ list.first()
+ } else {
+ null
+ }
+ }
+
+ private fun ActiveNotificationModel.toNotifAndPromotedContent(): NotifAndPromotedContent {
+ return NotifAndPromotedContent(this.key, this.promotedContent)
+ }
+
+ private val callNotification: Flow<NotifAndPromotedContent?> =
+ callChipInteractor.ongoingCallState
+ .map {
+ when (it) {
+ is OngoingCallModel.InCall ->
+ NotifAndPromotedContent(it.notificationKey, it.promotedContent)
+ is OngoingCallModel.NoCall -> null
+ }
+ }
+ .distinctUntilChanged()
+
+ private val promotedChipNotifications: Flow<List<NotifAndPromotedContent>> =
+ notifChipsInteractor.allNotificationChips
+ .map { chips -> chips.map { NotifAndPromotedContent(it.key, it.promotedContent) } }
+ .distinctUntilChanged()
+
/**
* This is the ordered list of notifications (and the promoted content) represented as chips in
* the status bar.
*/
private val orderedChipNotifications: Flow<List<NotifAndPromotedContent>> =
- combine(callChipInteractor.ongoingCallState, notifChipsInteractor.allNotificationChips) {
- callState,
- notifChips ->
- buildList {
- val callData = callState.getNotifData()?.also { add(it) }
- addAll(
- notifChips.mapNotNull {
- when (it.key) {
- callData?.key -> null // do not re-add the same call
- else -> NotifAndPromotedContent(it.key, it.promotedContent)
- }
- }
- )
+ combine(
+ screenRecordChipNotification,
+ mediaProjectionChipNotification,
+ callNotification,
+ promotedChipNotifications,
+ ) { screenRecordNotif, mediaProjectionNotif, callNotif, promotedNotifs ->
+ val chipNotifications = mutableListOf<NotifAndPromotedContent>()
+ val usedKeys = mutableListOf<String>()
+
+ fun addToList(item: NotifAndPromotedContent?) {
+ if (item != null && !usedKeys.contains(item.key)) {
+ chipNotifications.add(item)
+ usedKeys.add(item.key)
+ }
}
- }
- private fun OngoingCallModel.getNotifData(): NotifAndPromotedContent? =
- when (this) {
- is OngoingCallModel.InCall -> NotifAndPromotedContent(notificationKey, promotedContent)
- is OngoingCallModel.NoCall -> null
+ // IMPORTANT: This ordering is prescribed by OngoingActivityChipsViewModel. Be sure to
+ // always keep this ordering in sync with that view model.
+ // TODO(b/402471288): Create a single source of truth for the ordering.
+ addToList(screenRecordNotif)
+ addToList(mediaProjectionNotif)
+ addToList(callNotif)
+ promotedNotifs.forEach { addToList(it) }
+
+ chipNotifications
}
/**
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 2a3b266c8d10..9f89e71def78 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
@@ -976,7 +976,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mEntry;
}
- @Nullable
+ @NonNull
public EntryAdapter getEntryAdapter() {
NotificationBundleUi.unsafeAssertInNewMode();
return mEntryAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 292f74a65554..f36a0cf51b97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.Flags.notificationColorUpdateLogger;
import static com.android.systemui.Flags.physicalNotificationMovement;
+import static java.lang.Math.abs;
+
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.Configuration;
@@ -29,6 +31,7 @@ import android.util.FloatProperty;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;
@@ -110,14 +113,27 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
protected SpringAnimation mMagneticAnimator = new SpringAnimation(
this /* object */, DynamicAnimation.TRANSLATION_X);
+ private int mTouchSlop;
+
protected MagneticRowListener mMagneticRowListener = new MagneticRowListener() {
@Override
- public void setMagneticTranslation(float translation) {
- if (mMagneticAnimator.isRunning()) {
- mMagneticAnimator.animateToFinalPosition(translation);
- } else {
+ public void setMagneticTranslation(float translation, boolean trackEagerly) {
+ if (!mMagneticAnimator.isRunning()) {
setTranslation(translation);
+ return;
+ }
+
+ if (trackEagerly) {
+ float delta = abs(getTranslation() - translation);
+ if (delta > mTouchSlop) {
+ mMagneticAnimator.animateToFinalPosition(translation);
+ } else {
+ mMagneticAnimator.cancel();
+ setTranslation(translation);
+ }
+ } else {
+ mMagneticAnimator.animateToFinalPosition(translation);
}
}
@@ -183,6 +199,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
private void initDimens() {
mContentShift = getResources().getDimensionPixelSize(
R.dimen.shelf_transform_content_shift);
+ mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index cb1e898ef5b1..488aa44ddd3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1605,7 +1605,7 @@ public class NotificationContentView extends FrameLayout implements Notification
if (shouldShowBubbleButton(entry)) {
boolean isBubble = NotificationBundleUi.isEnabled()
- ? mContainingNotification.getEntryAdapter().isBubbleCapable()
+ ? mContainingNotification.getEntryAdapter().isBubble()
: entry.isBubble();
// explicitly resolve drawable resource using SystemUI's theme
Drawable d = mContext.getDrawable(isBubble
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 977936fa34fc..c03dc279888f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -46,7 +46,6 @@ import com.android.systemui.Flags;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.AlphaOptimizedImageView;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent;
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
@@ -363,7 +362,9 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
final float dismissThreshold = getDismissThreshold();
final boolean snappingToDismiss = delta < -dismissThreshold || delta > dismissThreshold;
if (mSnappingToDismiss != snappingToDismiss) {
- getMenuView().performHapticFeedback(CLOCK_TICK);
+ if (!Flags.magneticNotificationSwipes()) {
+ getMenuView().performHapticFeedback(CLOCK_TICK);
+ }
}
mSnappingToDismiss = snappingToDismiss;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index 53728c7da62d..487cbceb13a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -38,6 +38,10 @@ data class ActiveNotificationModel(
val groupKey: String?,
/** When this notification was posted. */
val whenTime: Long,
+ /** True if this is a foreground service notification. */
+ val isForegroundService: Boolean,
+ /** True if this notification is for an ongoing event. */
+ val isOngoingEvent: Boolean,
/** Is this entry in the ambient / minimized section (lowest priority)? */
val isAmbient: Boolean,
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt
index aa6951715755..48cff7497e3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt
@@ -33,12 +33,12 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
interface MagneticNotificationRowManager {
/**
- * Set the swipe threshold in pixels. After crossing the threshold, the magnetic target detaches
- * and the magnetic neighbors snap back.
+ * Notifies a change in the device density. The density can be used to compute the values of
+ * thresholds in pixels.
*
- * @param[threshold] Swipe threshold in pixels.
+ * @param[density] The device density.
*/
- fun setSwipeThresholdPx(thresholdPx: Float)
+ fun onDensityChange(density: Float)
/**
* Set the magnetic and roundable targets of a magnetic swipe interaction.
@@ -87,6 +87,9 @@ interface MagneticNotificationRowManager {
*/
fun onMagneticInteractionEnd(row: ExpandableNotificationRow, velocity: Float? = null)
+ /** Determine if the given [ExpandableNotificationRow] has been magnetically detached. */
+ fun isMagneticRowSwipeDetached(row: ExpandableNotificationRow): Boolean
+
/* Reset any roundness that magnetic targets may have */
fun resetRoundness()
@@ -104,12 +107,15 @@ interface MagneticNotificationRowManager {
/** Detaching threshold in dp */
const val MAGNETIC_DETACH_THRESHOLD_DP = 56
+ /** Re-attaching threshold in dp */
+ const val MAGNETIC_ATTACH_THRESHOLD_DP = 40
+
/* An empty implementation of a manager */
@JvmStatic
val Empty: MagneticNotificationRowManager
get() =
object : MagneticNotificationRowManager {
- override fun setSwipeThresholdPx(thresholdPx: Float) {}
+ override fun onDensityChange(density: Float) {}
override fun setMagneticAndRoundableTargets(
swipingRow: ExpandableNotificationRow,
@@ -127,6 +133,10 @@ interface MagneticNotificationRowManager {
velocity: Float?,
) {}
+ override fun isMagneticRowSwipeDetached(
+ row: ExpandableNotificationRow
+ ): Boolean = false
+
override fun resetRoundness() {}
override fun reset() {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
index 5a23f7cc2861..5c52500b7f70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
@@ -47,6 +47,7 @@ constructor(
private set
private var magneticDetachThreshold = Float.POSITIVE_INFINITY
+ private var magneticAttachThreshold = 0f
// Has the roundable target been set for the magnetic view that is being swiped.
val isSwipedViewRoundableSet: Boolean
@@ -57,13 +58,25 @@ constructor(
SpringForce().setStiffness(DETACH_STIFFNESS).setDampingRatio(DETACH_DAMPING_RATIO)
private val snapForce =
SpringForce().setStiffness(SNAP_BACK_STIFFNESS).setDampingRatio(SNAP_BACK_DAMPING_RATIO)
+ private val attachForce =
+ SpringForce().setStiffness(ATTACH_STIFFNESS).setDampingRatio(ATTACH_DAMPING_RATIO)
// Multiplier applied to the translation of a row while swiped
val swipedRowMultiplier =
MAGNETIC_TRANSLATION_MULTIPLIERS[MAGNETIC_TRANSLATION_MULTIPLIERS.size / 2]
- override fun setSwipeThresholdPx(thresholdPx: Float) {
- magneticDetachThreshold = thresholdPx
+ /**
+ * An offset applied to input translation that increases on subsequent re-attachments of a
+ * detached magnetic view. This helps keep computations consistent when the drag gesture input
+ * and the swiped notification don't share the same origin point after a re-attaching animation.
+ */
+ private var translationOffset = 0f
+
+ override fun onDensityChange(density: Float) {
+ magneticDetachThreshold =
+ density * MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
+ magneticAttachThreshold =
+ density * MagneticNotificationRowManager.MAGNETIC_ATTACH_THRESHOLD_DP
}
override fun setMagneticAndRoundableTargets(
@@ -72,6 +85,7 @@ constructor(
sectionsManager: NotificationSectionsManager,
) {
if (currentState == State.IDLE) {
+ translationOffset = 0f
updateMagneticAndRoundableTargets(swipingRow, stackScrollLayout, sectionsManager)
currentState = State.TARGETS_SET
} else {
@@ -121,42 +135,41 @@ constructor(
val canTargetBeDismissed =
currentMagneticListeners.swipedListener()?.canRowBeDismissed() ?: false
+ val correctedTranslation = translation - translationOffset
when (currentState) {
State.IDLE -> {
logger.logMagneticRowTranslationNotSet(currentState, row.getLoggingKey())
return false
}
State.TARGETS_SET -> {
- pullTargets(translation, canTargetBeDismissed)
+ pullTargets(correctedTranslation, canTargetBeDismissed)
currentState = State.PULLING
}
State.PULLING -> {
- updateRoundness(translation)
+ updateRoundness(correctedTranslation)
if (canTargetBeDismissed) {
- pullDismissibleRow(translation)
+ pullDismissibleRow(correctedTranslation)
} else {
- pullTargets(translation, canSwipedBeDismissed = false)
+ pullTargets(correctedTranslation, canSwipedBeDismissed = false)
}
}
State.DETACHED -> {
- val swiped = currentMagneticListeners.swipedListener()
- swiped?.setMagneticTranslation(translation)
+ translateDetachedRow(correctedTranslation)
}
}
return true
}
- private fun updateRoundness(translation: Float) {
+ private fun updateRoundness(translation: Float, animate: Boolean = false) {
val normalizedTranslation = abs(swipedRowMultiplier * translation) / magneticDetachThreshold
notificationRoundnessManager.setRoundnessForAffectedViews(
/* roundness */ normalizedTranslation.coerceIn(0f, MAX_PRE_DETACH_ROUNDNESS),
- /* animate */ false,
+ animate,
)
}
private fun pullDismissibleRow(translation: Float) {
- val targetTranslation = swipedRowMultiplier * translation
- val crossedThreshold = abs(targetTranslation) >= magneticDetachThreshold
+ val crossedThreshold = abs(translation) >= magneticDetachThreshold
if (crossedThreshold) {
snapNeighborsBack()
currentMagneticListeners.swipedListener()?.let { detach(it, translation) }
@@ -232,9 +245,30 @@ constructor(
)
}
+ private fun translateDetachedRow(translation: Float) {
+ val crossedThreshold = abs(translation) <= magneticAttachThreshold
+ if (crossedThreshold) {
+ translationOffset += translation
+ updateRoundness(translation = 0f, animate = true)
+ currentMagneticListeners.swipedListener()?.let { attach(it) }
+ currentState = State.PULLING
+ } else {
+ val swiped = currentMagneticListeners.swipedListener()
+ swiped?.setMagneticTranslation(translation, trackEagerly = false)
+ }
+ }
+
+ private fun attach(listener: MagneticRowListener) {
+ listener.cancelMagneticAnimations()
+ listener.triggerMagneticForce(endTranslation = 0f, attachForce)
+ msdlPlayer.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR)
+ }
+
override fun onMagneticInteractionEnd(row: ExpandableNotificationRow, velocity: Float?) {
+ translationOffset = 0f
if (row.isSwipedTarget()) {
when (currentState) {
+ State.TARGETS_SET -> currentState = State.IDLE
State.PULLING -> {
snapNeighborsBack(velocity)
currentState = State.IDLE
@@ -254,9 +288,13 @@ constructor(
}
}
+ override fun isMagneticRowSwipeDetached(row: ExpandableNotificationRow): Boolean =
+ row.isSwipedTarget() && currentState == State.DETACHED
+
override fun resetRoundness() = notificationRoundnessManager.clear()
override fun reset() {
+ translationOffset = 0f
currentMagneticListeners.forEach {
it?.cancelMagneticAnimations()
it?.cancelTranslationAnimations()
@@ -300,6 +338,8 @@ constructor(
private const val DETACH_DAMPING_RATIO = 0.95f
private const val SNAP_BACK_STIFFNESS = 550f
private const val SNAP_BACK_DAMPING_RATIO = 0.6f
+ private const val ATTACH_STIFFNESS = 800f
+ private const val ATTACH_DAMPING_RATIO = 0.95f
// Maximum value of corner roundness that gets applied during the pre-detach dragging
private const val MAX_PRE_DETACH_ROUNDNESS = 0.8f
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
index 5959ef1e093b..344dab4369f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
@@ -21,8 +21,17 @@ import androidx.dynamicanimation.animation.SpringForce
/** A listener that responds to magnetic forces applied to an [ExpandableNotificationRow] */
interface MagneticRowListener {
- /** Set a translation due to a magnetic attachment. */
- fun setMagneticTranslation(translation: Float)
+ /**
+ * Set a translation due to a magnetic attachment.
+ *
+ * If a magnetic animation is running, [trackEagerly] decides if the new translation is applied
+ * immediately or if the animation finishes first. When applying the translation immediately,
+ * the change in translation must be greater than a touch slop threshold.
+ *
+ * @param[translation] Incoming gesture translation.
+ * @param[trackEagerly] Whether we eagerly track the incoming translation or not.
+ */
+ fun setMagneticTranslation(translation: Float, trackEagerly: Boolean = true)
/**
* Trigger the magnetic behavior when the row detaches or snaps back from its magnetic
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index f3d8ee245540..612c19fc6696 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -486,15 +486,22 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
@Override
+ public boolean isMagneticViewDetached(View view) {
+ if (view instanceof ExpandableNotificationRow row) {
+ return mMagneticNotificationRowManager.isMagneticRowSwipeDetached(row);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
public float getTotalTranslationLength(View animView) {
return mView.getTotalTranslationLength(animView);
}
@Override
public void onDensityScaleChange(float density) {
- mMagneticNotificationRowManager.setSwipeThresholdPx(
- density * MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
- );
+ mMagneticNotificationRowManager.onDensityChange(density);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index c5a846e1da05..5105e55b0a5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -255,12 +255,13 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
int menuSnapTarget = menuRow.getMenuSnapTarget();
boolean isNonFalseMenuRevealingGesture =
isMenuRevealingGestureAwayFromMenu && !isFalseGesture();
+ boolean isMagneticViewDetached = mCallback.isMagneticViewDetached(animView);
if ((isNonDismissGestureTowardsMenu || isNonFalseMenuRevealingGesture)
&& menuSnapTarget != 0) {
// Menu has not been snapped to previously and this is menu revealing gesture
snapOpen(animView, menuSnapTarget, velocity);
menuRow.onSnapOpen();
- } else if (isDismissGesture && !gestureTowardsMenu) {
+ } else if (isDismissGesture && (!gestureTowardsMenu || isMagneticViewDetached)) {
dismiss(animView, velocity);
menuRow.onDismiss();
} else {
@@ -272,6 +273,7 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
private void handleSwipeFromOpenState(MotionEvent ev, View animView, float velocity,
NotificationMenuRowPlugin menuRow) {
boolean isDismissGesture = isDismissGesture(ev);
+ boolean isMagneticViewDetached = mCallback.isMagneticViewDetached(animView);
final boolean withinSnapMenuThreshold =
menuRow.isWithinSnapMenuThreshold();
@@ -280,7 +282,7 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
// Haven't moved enough to unsnap from the menu
menuRow.onSnapOpen();
snapOpen(animView, menuRow.getMenuSnapTarget(), velocity);
- } else if (isDismissGesture && !menuRow.shouldSnapBack()) {
+ } else if (isDismissGesture && (!menuRow.shouldSnapBack() || isMagneticViewDetached)) {
// Only dismiss if we're not moving towards the menu
dismiss(animView, velocity);
menuRow.onDismiss();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index db1977b3ff45..93489e90fb85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -49,6 +49,7 @@ import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIc
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairosImpl
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModelKairos
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl
import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
@@ -94,6 +95,7 @@ import kotlinx.coroutines.flow.Flow
MobileRepositorySwitcherKairos.Module::class,
MobileConnectionsRepositoryKairosImpl.Module::class,
MobileIconsInteractorKairosImpl.Module::class,
+ MobileIconsViewModelKairos.Module::class,
MobileConnectionRepositoryKairosFactoryImpl.Module::class,
MobileConnectionsRepositoryKairosAdapter.Module::class,
MobileIconsInteractorKairosAdapter.Module::class,
@@ -217,6 +219,7 @@ abstract class StatusBarPipelineModule {
fun provideFirstMobileSubShowingNetworkTypeIconProvider(
mobileIconsViewModel: MobileIconsViewModel
): Supplier<Flow<Boolean>> {
+ // TODO: kairos-ify
return Supplier<Flow<Boolean>> {
mobileIconsViewModel.firstMobileSubShowingNetworkTypeIcon
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
index a9399593973b..3d58f84e1f91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
@@ -48,6 +48,8 @@ interface MobileIconInteractorKairos {
/** The table log created for this connection */
val tableLogBuffer: TableLogBuffer
+ val subscriptionId: Int
+
/** The current mobile data activity */
val activity: State<DataActivityModel>
@@ -146,6 +148,9 @@ class MobileIconInteractorKairosImpl(
private val carrierIdOverrides: MobileIconCarrierIdOverrides =
MobileIconCarrierIdOverridesImpl(),
) : MobileIconInteractorKairos, KairosBuilder by kairosBuilder() {
+ override val subscriptionId: Int
+ get() = connectionRepository.subId
+
override val tableLogBuffer: TableLogBuffer
get() = connectionRepository.tableLogBuffer
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
index fa9fa4c1366f..32ebe884062d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
@@ -24,7 +24,7 @@ import com.android.systemui.statusbar.pipeline.icons.shared.model.BindableIcon
import com.android.systemui.statusbar.pipeline.icons.shared.model.ModernStatusBarViewCreator
import com.android.systemui.statusbar.pipeline.mobile.ui.binder.StackedMobileIconBinder
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ui.view.SingleBindableStatusBarComposeIconView
import javax.inject.Inject
@@ -34,7 +34,7 @@ class StackedMobileBindableIcon
constructor(
context: Context,
mobileIconsViewModel: MobileIconsViewModel,
- viewModelFactory: StackedMobileIconViewModel.Factory,
+ viewModelFactory: StackedMobileIconViewModelImpl.Factory,
) : BindableIcon {
override val slot: String =
context.getString(com.android.internal.R.string.status_bar_stacked_mobile)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
index c9fc53ecadc0..fef5bfe2b7d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
@@ -25,7 +25,7 @@ import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
import com.android.systemui.statusbar.pipeline.shared.ui.composable.StackedMobileIcon
import com.android.systemui.statusbar.pipeline.shared.ui.view.SingleBindableStatusBarComposeIconView
@@ -34,7 +34,7 @@ object StackedMobileIconBinder {
fun bind(
view: SingleBindableStatusBarComposeIconView,
mobileIconsViewModel: MobileIconsViewModel,
- viewModelFactory: StackedMobileIconViewModel.Factory,
+ viewModelFactory: StackedMobileIconViewModelImpl.Factory,
): ModernStatusBarViewBinding {
return SingleBindableStatusBarComposeIconView.withDefaultBinding(
view = view,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
index fce8c85338f3..d2e3a1489040 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -17,14 +17,12 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
import android.graphics.Color
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.stateIn
/**
* A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This
@@ -35,45 +33,47 @@ import kotlinx.coroutines.flow.stateIn
* @property location the [StatusBarLocation] of this VM.
* @property verboseLogger an optional logger to log extremely verbose view updates.
*/
+@ExperimentalKairosApi
abstract class LocationBasedMobileViewModelKairos(
- val commonImpl: MobileIconViewModelCommonKairos,
+ val commonImpl: MobileIconViewModelKairosCommon,
val location: StatusBarLocation,
val verboseLogger: VerboseMobileViewLogger?,
-) : MobileIconViewModelCommonKairos by commonImpl {
+) : MobileIconViewModelKairosCommon by commonImpl {
val defaultColor: Int = Color.WHITE
companion object {
fun viewModelForLocation(
- commonImpl: MobileIconViewModelCommon,
- interactor: MobileIconInteractor,
+ commonImpl: MobileIconViewModelKairosCommon,
+ interactor: MobileIconInteractorKairos,
verboseMobileViewLogger: VerboseMobileViewLogger,
location: StatusBarLocation,
- scope: CoroutineScope,
- ): LocationBasedMobileViewModel =
+ ): LocationBasedMobileViewModelKairos =
when (location) {
StatusBarLocation.HOME ->
- HomeMobileIconViewModel(commonImpl, verboseMobileViewLogger)
- StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModel(commonImpl)
- StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl)
+ HomeMobileIconViewModelKairos(commonImpl, verboseMobileViewLogger)
+ StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModelKairos(commonImpl)
+ StatusBarLocation.QS -> QsMobileIconViewModelKairos(commonImpl)
StatusBarLocation.SHADE_CARRIER_GROUP ->
- ShadeCarrierGroupMobileIconViewModel(commonImpl, interactor, scope)
+ ShadeCarrierGroupMobileIconViewModelKairos(commonImpl, interactor)
}
}
}
+@ExperimentalKairosApi
class HomeMobileIconViewModelKairos(
- commonImpl: MobileIconViewModelCommonKairos,
+ commonImpl: MobileIconViewModelKairosCommon,
verboseMobileViewLogger: VerboseMobileViewLogger,
) :
- MobileIconViewModelCommonKairos,
+ MobileIconViewModelKairosCommon,
LocationBasedMobileViewModelKairos(
commonImpl,
location = StatusBarLocation.HOME,
verboseMobileViewLogger,
)
-class QsMobileIconViewModelKairos(commonImpl: MobileIconViewModelCommonKairos) :
- MobileIconViewModelCommonKairos,
+@ExperimentalKairosApi
+class QsMobileIconViewModelKairos(commonImpl: MobileIconViewModelKairosCommon) :
+ MobileIconViewModelKairosCommon,
LocationBasedMobileViewModelKairos(
commonImpl,
location = StatusBarLocation.QS,
@@ -81,30 +81,34 @@ class QsMobileIconViewModelKairos(commonImpl: MobileIconViewModelCommonKairos) :
verboseLogger = null,
)
+@ExperimentalKairosApi
class ShadeCarrierGroupMobileIconViewModelKairos(
- commonImpl: MobileIconViewModelCommonKairos,
- interactor: MobileIconInteractor,
- scope: CoroutineScope,
+ commonImpl: MobileIconViewModelKairosCommon,
+ private val interactor: MobileIconInteractorKairos,
) :
- MobileIconViewModelCommonKairos,
+ MobileIconViewModelKairosCommon,
LocationBasedMobileViewModelKairos(
commonImpl,
location = StatusBarLocation.SHADE_CARRIER_GROUP,
// Only do verbose logging for the Home location.
verboseLogger = null,
) {
- private val isSingleCarrier = interactor.isSingleCarrier
- val carrierName = interactor.carrierName
- override val isVisible: StateFlow<Boolean> =
+ private val isSingleCarrier: State<Boolean>
+ get() = interactor.isSingleCarrier
+
+ val carrierName: State<String>
+ get() = interactor.carrierName
+
+ override val isVisible: State<Boolean> =
combine(super.isVisible, isSingleCarrier) { isVisible, isSingleCarrier ->
- if (isSingleCarrier) false else isVisible
- }
- .stateIn(scope, SharingStarted.WhileSubscribed(), super.isVisible.value)
+ !isSingleCarrier && isVisible
+ }
}
-class KeyguardMobileIconViewModelKairos(commonImpl: MobileIconViewModelCommonKairos) :
- MobileIconViewModelCommonKairos,
+@ExperimentalKairosApi
+class KeyguardMobileIconViewModelKairos(commonImpl: MobileIconViewModelKairosCommon) :
+ MobileIconViewModelKairosCommon,
LocationBasedMobileViewModelKairos(
commonImpl,
location = StatusBarLocation.KEYGUARD,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
index cc7fc0964dae..0a0f9640a920 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -17,206 +17,192 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
import com.android.systemui.Flags.statusBarStaticInoutIndicators
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.res.R
import com.android.systemui.statusbar.core.NewStatusBarIcons
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
/** Common interface for all of the location-based mobile icon view models. */
-interface MobileIconViewModelCommonKairos : MobileIconViewModelCommon {
- override val subscriptionId: Int
+@ExperimentalKairosApi
+interface MobileIconViewModelKairosCommon {
+ val subscriptionId: Int
+ val iconInteractor: MobileIconInteractorKairos
/** True if this view should be visible at all. */
- override val isVisible: StateFlow<Boolean>
- override val icon: Flow<SignalIconModel>
- override val contentDescription: Flow<MobileContentDescription?>
- override val roaming: Flow<Boolean>
+ val isVisible: KairosState<Boolean>
+ val icon: KairosState<SignalIconModel>
+ val contentDescription: KairosState<MobileContentDescription?>
+ val roaming: KairosState<Boolean>
/** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
- override val networkTypeIcon: Flow<Icon.Resource?>
+ val networkTypeIcon: KairosState<Icon.Resource?>
/** The slice attribution. Drawn as a background layer */
- override val networkTypeBackground: StateFlow<Icon.Resource?>
- override val activityInVisible: Flow<Boolean>
- override val activityOutVisible: Flow<Boolean>
- override val activityContainerVisible: Flow<Boolean>
+ val networkTypeBackground: KairosState<Icon.Resource?>
+ val activityInVisible: KairosState<Boolean>
+ val activityOutVisible: KairosState<Boolean>
+ val activityContainerVisible: KairosState<Boolean>
}
/**
* View model for the state of a single mobile icon. Each [MobileIconViewModel] will keep watch over
- * a single line of service via [MobileIconInteractor] and update the UI based on that
+ * a single line of service via [MobileIconInteractorKairos] and update the UI based on that
* subscription's information.
*
- * There will be exactly one [MobileIconViewModel] per filtered subscription offered from
- * [MobileIconsInteractor.filteredSubscriptions].
+ * There will be exactly one [MobileIconViewModelKairos] per filtered subscription offered from
+ * [MobileIconsInteractorKairos.filteredSubscriptions].
*
- * For the sake of keeping log spam in check, every flow funding the [MobileIconViewModelCommon]
- * interface is implemented as a [StateFlow]. This ensures that each location-based mobile icon view
- * model gets the exact same information, as well as allows us to log that unified state only once
- * per icon.
+ * For the sake of keeping log spam in check, every flow funding the
+ * [MobileIconViewModelKairosCommon] interface is implemented as a [StateFlow]. This ensures that
+ * each location-based mobile icon view model gets the exact same information, as well as allows us
+ * to log that unified state only once per icon.
*/
+@ExperimentalKairosApi
class MobileIconViewModelKairos(
override val subscriptionId: Int,
- iconInteractor: MobileIconInteractor,
- airplaneModeInteractor: AirplaneModeInteractor,
- constants: ConnectivityConstants,
- scope: CoroutineScope,
-) : MobileIconViewModelCommonKairos {
- private val cellProvider by lazy {
- CellularIconViewModelKairos(
- subscriptionId,
- iconInteractor,
- airplaneModeInteractor,
- constants,
- scope,
- )
+ override val iconInteractor: MobileIconInteractorKairos,
+ private val airplaneModeInteractor: AirplaneModeInteractor,
+ private val constants: ConnectivityConstants,
+ private val flags: FeatureFlagsClassic,
+) : MobileIconViewModelKairosCommon, KairosBuilder by kairosBuilder() {
+
+ private val isAirplaneMode: State<Boolean> = buildState {
+ airplaneModeInteractor.isAirplaneMode.toState()
}
private val satelliteProvider by lazy {
- CarrierBasedSatelliteViewModelKairosImpl(
- subscriptionId,
- airplaneModeInteractor,
- iconInteractor,
- scope,
- )
+ CarrierBasedSatelliteViewModelKairosImpl(subscriptionId, iconInteractor, isAirplaneMode)
}
/**
* Similar to repository switching, this allows us to split up the logic of satellite/cellular
* states, since they are different by nature
*/
- private val vmProvider: Flow<MobileIconViewModelCommon> =
- iconInteractor.isNonTerrestrial
- .mapLatest { nonTerrestrial ->
- if (nonTerrestrial) {
- satelliteProvider
- } else {
- cellProvider
+ private val vmProvider: KairosState<MobileIconViewModelKairosCommon> = buildState {
+ iconInteractor.isNonTerrestrial.mapLatestBuild { nonTerrestrial ->
+ if (nonTerrestrial) {
+ satelliteProvider
+ } else {
+ activated {
+ CellularIconViewModelKairos(
+ subscriptionId,
+ iconInteractor,
+ airplaneModeInteractor,
+ constants,
+ flags,
+ )
}
}
- .stateIn(scope, SharingStarted.WhileSubscribed(), cellProvider)
+ }
+ }
- override val isVisible: StateFlow<Boolean> =
- vmProvider
- .flatMapLatest { it.isVisible }
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val isVisible: KairosState<Boolean> = vmProvider.flatMap { it.isVisible }
- override val icon: Flow<SignalIconModel> = vmProvider.flatMapLatest { it.icon }
+ override val icon: KairosState<SignalIconModel> = vmProvider.flatMap { it.icon }
- override val contentDescription: Flow<MobileContentDescription?> =
- vmProvider.flatMapLatest { it.contentDescription }
+ override val contentDescription: KairosState<MobileContentDescription?> =
+ vmProvider.flatMap { it.contentDescription }
- override val roaming: Flow<Boolean> = vmProvider.flatMapLatest { it.roaming }
+ override val roaming: KairosState<Boolean> = vmProvider.flatMap { it.roaming }
- override val networkTypeIcon: Flow<Icon.Resource?> =
- vmProvider.flatMapLatest { it.networkTypeIcon }
+ override val networkTypeIcon: KairosState<Icon.Resource?> =
+ vmProvider.flatMap { it.networkTypeIcon }
- override val networkTypeBackground: StateFlow<Icon.Resource?> =
- vmProvider
- .flatMapLatest { it.networkTypeBackground }
- .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ override val networkTypeBackground: KairosState<Icon.Resource?> =
+ vmProvider.flatMap { it.networkTypeBackground }
- override val activityInVisible: Flow<Boolean> =
- vmProvider.flatMapLatest { it.activityInVisible }
+ override val activityInVisible: KairosState<Boolean> =
+ vmProvider.flatMap { it.activityInVisible }
- override val activityOutVisible: Flow<Boolean> =
- vmProvider.flatMapLatest { it.activityOutVisible }
+ override val activityOutVisible: KairosState<Boolean> =
+ vmProvider.flatMap { it.activityOutVisible }
- override val activityContainerVisible: Flow<Boolean> =
- vmProvider.flatMapLatest { it.activityContainerVisible }
+ override val activityContainerVisible: KairosState<Boolean> =
+ vmProvider.flatMap { it.activityContainerVisible }
}
/** Representation of this network when it is non-terrestrial (e.g., satellite) */
+@ExperimentalKairosApi
private class CarrierBasedSatelliteViewModelKairosImpl(
override val subscriptionId: Int,
- airplaneModeInteractor: AirplaneModeInteractor,
- interactor: MobileIconInteractor,
- scope: CoroutineScope,
-) : MobileIconViewModelCommon, MobileIconViewModelCommonKairos {
- override val isVisible: StateFlow<Boolean> =
- airplaneModeInteractor.isAirplaneMode
- .map { !it }
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
- override val icon: Flow<SignalIconModel> = interactor.signalLevelIcon
+ override val iconInteractor: MobileIconInteractorKairos,
+ isAirplaneMode: KairosState<Boolean>,
+) : MobileIconViewModelKairosCommon {
+ override val isVisible: KairosState<Boolean> = isAirplaneMode.map { !it }
+ override val icon: KairosState<SignalIconModel>
+ get() = iconInteractor.signalLevelIcon
- override val contentDescription: Flow<MobileContentDescription?> = MutableStateFlow(null)
+ override val contentDescription: KairosState<MobileContentDescription?> = stateOf(null)
/** These fields are not used for satellite icons currently */
- override val roaming: Flow<Boolean> = flowOf(false)
- override val networkTypeIcon: Flow<Icon.Resource?> = flowOf(null)
- override val networkTypeBackground: StateFlow<Icon.Resource?> = MutableStateFlow(null)
- override val activityInVisible: Flow<Boolean> = flowOf(false)
- override val activityOutVisible: Flow<Boolean> = flowOf(false)
- override val activityContainerVisible: Flow<Boolean> = flowOf(false)
+ override val roaming: KairosState<Boolean> = stateOf(false)
+ override val networkTypeIcon: KairosState<Icon.Resource?> = stateOf(null)
+ override val networkTypeBackground: KairosState<Icon.Resource?> = stateOf(null)
+ override val activityInVisible: KairosState<Boolean> = stateOf(false)
+ override val activityOutVisible: KairosState<Boolean> = stateOf(false)
+ override val activityContainerVisible: KairosState<Boolean> = stateOf(false)
}
/** Terrestrial (cellular) icon. */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@ExperimentalKairosApi
private class CellularIconViewModelKairos(
override val subscriptionId: Int,
- iconInteractor: MobileIconInteractor,
+ override val iconInteractor: MobileIconInteractorKairos,
airplaneModeInteractor: AirplaneModeInteractor,
constants: ConnectivityConstants,
- scope: CoroutineScope,
-) : MobileIconViewModelCommon, MobileIconViewModelCommonKairos {
- override val isVisible: StateFlow<Boolean> =
+ flags: FeatureFlagsClassic,
+) : MobileIconViewModelKairosCommon, KairosBuilder by kairosBuilder() {
+
+ override val isVisible: KairosState<Boolean> =
if (!constants.hasDataCapabilities) {
- flowOf(false)
- } else {
+ stateOf(false)
+ } else {
+ buildState {
combine(
- airplaneModeInteractor.isAirplaneMode,
- iconInteractor.isAllowedDuringAirplaneMode,
- iconInteractor.isForceHidden,
- ) { isAirplaneMode, isAllowedDuringAirplaneMode, isForceHidden ->
- if (isForceHidden) {
- false
- } else if (isAirplaneMode) {
- isAllowedDuringAirplaneMode
- } else {
- true
+ airplaneModeInteractor.isAirplaneMode.toState(),
+ iconInteractor.isAllowedDuringAirplaneMode,
+ iconInteractor.isForceHidden,
+ ) { isAirplaneMode, isAllowedDuringAirplaneMode, isForceHidden ->
+ if (isForceHidden) {
+ false
+ } else if (isAirplaneMode) {
+ isAllowedDuringAirplaneMode
+ } else {
+ true
+ }
+ }
+ .also {
+ logDiffsForTable(it, iconInteractor.tableLogBuffer, columnName = "visible")
}
- }
}
- .distinctUntilChanged()
- .logDiffsForTable(
- iconInteractor.tableLogBuffer,
- columnName = "visible",
- initialValue = false,
- )
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ }
- override val icon: Flow<SignalIconModel> = iconInteractor.signalLevelIcon
+ override val icon: KairosState<SignalIconModel>
+ get() = iconInteractor.signalLevelIcon
- override val contentDescription: Flow<MobileContentDescription?> =
+ override val contentDescription: KairosState<MobileContentDescription?> =
combine(iconInteractor.signalLevelIcon, iconInteractor.networkName) { icon, nameModel ->
- when (icon) {
- is SignalIconModel.Cellular ->
- MobileContentDescription.Cellular(
- nameModel.name,
- icon.levelDescriptionRes(),
- )
- else -> null
- }
+ when (icon) {
+ is SignalIconModel.Cellular ->
+ MobileContentDescription.Cellular(nameModel.name, icon.levelDescriptionRes())
+ else -> null
}
- .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ }
private fun SignalIconModel.Cellular.levelDescriptionRes() =
when (level) {
@@ -241,7 +227,7 @@ private class CellularIconViewModelKairos(
else -> R.string.accessibility_no_signal
}
- private val showNetworkTypeIcon: Flow<Boolean> =
+ private val showNetworkTypeIcon: KairosState<Boolean> =
combine(
iconInteractor.isDataConnected,
iconInteractor.isDataEnabled,
@@ -252,77 +238,72 @@ private class CellularIconViewModelKairos(
alwaysShow ||
(!carrierNetworkChange && (dataEnabled && dataConnected && mobileIsDefault))
}
- .distinctUntilChanged()
- .logDiffsForTable(
- iconInteractor.tableLogBuffer,
- columnName = "showNetworkTypeIcon",
- initialValue = false,
- )
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
- override val networkTypeIcon: Flow<Icon.Resource?> =
- combine(iconInteractor.networkTypeIconGroup, showNetworkTypeIcon) {
- networkTypeIconGroup,
- shouldShow ->
- val desc =
- if (networkTypeIconGroup.contentDescription != 0)
- ContentDescription.Resource(networkTypeIconGroup.contentDescription)
- else null
- val icon =
- if (networkTypeIconGroup.iconId != 0)
- Icon.Resource(networkTypeIconGroup.iconId, desc)
- else null
- return@combine when {
- !shouldShow -> null
- else -> icon
+ .also {
+ onActivated {
+ logDiffsForTable(
+ it,
+ iconInteractor.tableLogBuffer,
+ columnName = "showNetworkTypeIcon",
+ )
}
}
- .distinctUntilChanged()
- .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
- override val networkTypeBackground =
- iconInteractor.showSliceAttribution
- .map {
- when {
- it && NewStatusBarIcons.isEnabled ->
- Icon.Resource(R.drawable.mobile_network_type_background_updated, null)
- it -> Icon.Resource(R.drawable.mobile_network_type_background, null)
- else -> null
+
+ override val networkTypeIcon: KairosState<Icon.Resource?> =
+ combine(iconInteractor.networkTypeIconGroup, showNetworkTypeIcon) {
+ networkTypeIconGroup,
+ shouldShow ->
+ val desc =
+ if (networkTypeIconGroup.contentDescription != 0) {
+ ContentDescription.Resource(networkTypeIconGroup.contentDescription)
+ } else {
+ null
+ }
+ val icon =
+ if (networkTypeIconGroup.iconId != 0) {
+ Icon.Resource(networkTypeIconGroup.iconId, desc)
+ } else {
+ null
}
+ when {
+ !shouldShow -> null
+ else -> icon
}
- .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
- override val roaming: StateFlow<Boolean> =
- iconInteractor.isRoaming
- .logDiffsForTable(
- iconInteractor.tableLogBuffer,
- columnName = "roaming",
- initialValue = false,
- )
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
- private val activity: Flow<DataActivityModel?> =
+ }
+
+ override val networkTypeBackground: KairosState<Icon.Resource?> =
+ iconInteractor.showSliceAttribution.map {
+ when {
+ it && NewStatusBarIcons.isEnabled ->
+ Icon.Resource(R.drawable.mobile_network_type_background_updated, null)
+ it -> Icon.Resource(R.drawable.mobile_network_type_background, null)
+ else -> null
+ }
+ }
+
+ override val roaming: KairosState<Boolean> =
+ iconInteractor.isRoaming.also {
+ onActivated {
+ logDiffsForTable(it, iconInteractor.tableLogBuffer, columnName = "roaming")
+ }
+ }
+
+ private val activity: KairosState<DataActivityModel?> =
if (!constants.shouldShowActivityConfig) {
- flowOf(null)
+ stateOf(null)
} else {
iconInteractor.activity
}
- override val activityInVisible: Flow<Boolean> =
- activity
- .map { it?.hasActivityIn ?: false }
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val activityInVisible: KairosState<Boolean> =
+ activity.map { it?.hasActivityIn ?: false }
- override val activityOutVisible: Flow<Boolean> =
- activity
- .map { it?.hasActivityOut ?: false }
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ override val activityOutVisible: KairosState<Boolean> =
+ activity.map { it?.hasActivityOut ?: false }
- override val activityContainerVisible: Flow<Boolean> =
+ override val activityContainerVisible: KairosState<Boolean> =
if (statusBarStaticInoutIndicators()) {
- flowOf(constants.shouldShowActivityConfig)
- } else {
- activity.map { it != null && (it.hasActivityIn || it.hasActivityOut) }
- }
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+ stateOf(constants.shouldShowActivityConfig)
+ } else {
+ activity.map { it != null && (it.hasActivityIn || it.hasActivityOut) }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
index a65540738828..ada5500a6f3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -16,137 +16,149 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
-import androidx.annotation.VisibleForTesting
-import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.systemui.coroutines.newTracingContext
+import androidx.compose.runtime.State as ComposeState
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.BuildSpec
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.changes
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatten
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairos
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import java.util.concurrent.ConcurrentHashMap
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
+import javax.inject.Provider
/**
* View model for describing the system's current mobile cellular connections. The result is a list
* of [MobileIconViewModel]s which describe the individual icons and can be bound to
* [ModernStatusBarMobileView].
*/
+@ExperimentalKairosApi
@SysUISingleton
class MobileIconsViewModelKairos
@Inject
constructor(
val logger: MobileViewLogger,
private val verboseLogger: VerboseMobileViewLogger,
- private val interactor: MobileIconsInteractor,
+ private val interactor: MobileIconsInteractorKairos,
private val airplaneModeInteractor: AirplaneModeInteractor,
private val constants: ConnectivityConstants,
- @Background private val scope: CoroutineScope,
-) {
- @VisibleForTesting
- val reuseCache = ConcurrentHashMap<Int, Pair<MobileIconViewModel, CoroutineScope>>()
+ private val flags: FeatureFlagsClassic,
+) : KairosBuilder by kairosBuilder() {
- val activeMobileDataSubscriptionId: StateFlow<Int?> = interactor.activeMobileDataSubscriptionId
+ val activeSubscriptionId: State<Int?>
+ get() = interactor.activeDataIconInteractor.map { it?.subscriptionId }
- val subscriptionIdsFlow: StateFlow<List<Int>> =
- interactor.filteredSubscriptions
- .mapLatest { subscriptions ->
- subscriptions.map { subscriptionModel -> subscriptionModel.subscriptionId }
- }
- .stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
-
- val mobileSubViewModels: StateFlow<List<MobileIconViewModelCommon>> =
- subscriptionIdsFlow
- .map { ids -> ids.map { commonViewModelForSub(it) } }
- .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
+ val subscriptionIds: KairosState<List<Int>> =
+ interactor.filteredSubscriptions.map { subscriptions ->
+ subscriptions.map { it.subscriptionId }
+ }
- private val firstMobileSubViewModel: StateFlow<MobileIconViewModelCommon?> =
- mobileSubViewModels
- .map {
- if (it.isEmpty()) {
- null
- } else {
- // Mobile icons get reversed by [StatusBarIconController], so the last element
- // in this list will show up visually first.
- it.last()
- }
- }
- .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+ val icons: Incremental<Int, MobileIconViewModelKairos> = buildIncremental {
+ interactor.icons
+ .mapValues { (subId, icon) -> buildSpec { commonViewModel(subId, icon) } }
+ .applyLatestSpecForKey()
+ }
- /**
- * A flow that emits `true` if the mobile sub that's displayed first visually is showing its
- * network type icon and `false` otherwise.
- */
- val firstMobileSubShowingNetworkTypeIcon: StateFlow<Boolean> =
- firstMobileSubViewModel
- .flatMapLatest { firstMobileSubViewModel ->
- firstMobileSubViewModel?.networkTypeIcon?.map { it != null } ?: flowOf(false)
+ /** Whether the mobile sub that's displayed first visually is showing its network type icon. */
+ val firstMobileSubShowingNetworkTypeIcon: KairosState<Boolean> = buildState {
+ combine(subscriptionIds.map { it.lastOrNull() }, icons) { lastId, icons ->
+ icons[lastId]?.networkTypeIcon?.map { it != null } ?: stateOf(false)
}
- .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
- val isStackable: StateFlow<Boolean> = interactor.isStackable
-
- init {
- scope.launch { subscriptionIdsFlow.collect { invalidateCaches(it) } }
+ .flatten()
}
- fun viewModelForSub(subId: Int, location: StatusBarLocation): LocationBasedMobileViewModel {
- val common = commonViewModelForSub(subId)
- return LocationBasedMobileViewModel.viewModelForLocation(
- common,
- interactor.getMobileConnectionInteractorForSubId(subId),
+ val isStackable: KairosState<Boolean>
+ get() = interactor.isStackable
+
+ fun viewModelForSub(
+ subId: Int,
+ location: StatusBarLocation,
+ ): BuildSpec<LocationBasedMobileViewModelKairos> = buildSpec {
+ val iconInteractor =
+ interactor.icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+ val commonViewModel =
+ icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+ LocationBasedMobileViewModelKairos.viewModelForLocation(
+ commonViewModel,
+ iconInteractor,
verboseLogger,
location,
- scope,
)
}
- private fun commonViewModelForSub(subId: Int): MobileIconViewModelCommon {
- return reuseCache.getOrPut(subId) { createViewModel(subId) }.first
- }
-
- private fun createViewModel(subId: Int): Pair<MobileIconViewModel, CoroutineScope> {
- // Create a child scope so we can cancel it
- val vmScope = scope.createChildScope(newTracingContext("MobileIconViewModel"))
- val vm =
- MobileIconViewModel(
- subId,
- interactor.getMobileConnectionInteractorForSubId(subId),
- airplaneModeInteractor,
- constants,
- vmScope,
+ fun shadeCarrierGroupIcon(subId: Int): BuildSpec<ShadeCarrierGroupMobileIconViewModelKairos> =
+ buildSpec {
+ val iconInteractor =
+ interactor.icons.sample().getOrElse(subId) {
+ error("Unknown subscription id: $subId")
+ }
+ val commonViewModel =
+ icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+ ShadeCarrierGroupMobileIconViewModelKairos(commonViewModel, iconInteractor)
+ }
+
+ private fun BuildScope.commonViewModel(subId: Int, iconInteractor: MobileIconInteractorKairos) =
+ activated {
+ MobileIconViewModelKairos(
+ subscriptionId = subId,
+ iconInteractor = iconInteractor,
+ airplaneModeInteractor = airplaneModeInteractor,
+ constants = constants,
+ flags = flags,
)
-
- return Pair(vm, vmScope)
+ }
+
+ @dagger.Module
+ object Module {
+ @Provides
+ @ElementsIntoSet
+ fun bindKairosActivatable(
+ impl: Provider<MobileIconsViewModelKairos>
+ ): Set<@JvmSuppressWildcards KairosActivatable> =
+ if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
}
+}
- private fun CoroutineScope.createChildScope(extraContext: CoroutineContext) =
- CoroutineScope(coroutineContext + Job(coroutineContext[Job]) + extraContext)
+@ExperimentalKairosApi
+class MobileIconsViewModelKairosComposeWrapper(
+ val icons: ComposeState<Map<Int, MobileIconViewModelKairos>>
+)
- private fun invalidateCaches(subIds: List<Int>) {
- reuseCache.keys
- .filter { !subIds.contains(it) }
- .forEach { id ->
- reuseCache
- .remove(id)
- // Cancel the view model's scope after removing it
- ?.second
- ?.cancel()
- }
- }
+@ExperimentalKairosApi
+fun composeWrapper(
+ viewModel: MobileIconsViewModelKairos
+): BuildSpec<MobileIconsViewModelKairosComposeWrapper> = buildSpec {
+ MobileIconsViewModelKairosComposeWrapper(icons = toComposeState(viewModel.icons))
+}
+
+@ExperimentalKairosApi
+fun <T> BuildScope.toComposeState(state: KairosState<T>): ComposeState<T> {
+ val initial = state.sample()
+ val cState = mutableStateOf(initial)
+ state.changes.observe { cState.value = it }
+ return cState
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
index 2c85a5150575..060454c2b1c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
@@ -22,6 +22,7 @@ import com.android.systemui.common.shared.model.Icon
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel.DualSim
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -30,10 +31,22 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
+interface StackedMobileIconViewModel {
+ val dualSim: DualSim?
+ val networkTypeIcon: Icon.Resource?
+ val isIconVisible: Boolean
+
+ data class DualSim(
+ val primary: SignalIconModel.Cellular,
+ val secondary: SignalIconModel.Cellular,
+ )
+}
+
@OptIn(ExperimentalCoroutinesApi::class)
-class StackedMobileIconViewModel
+class StackedMobileIconViewModelImpl
@AssistedInject
-constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable() {
+constructor(mobileIconsViewModel: MobileIconsViewModel) :
+ ExclusiveActivatable(), StackedMobileIconViewModel {
private val hydrator = Hydrator("StackedMobileIconViewModel")
private val isStackable: Boolean by
@@ -52,7 +65,7 @@ constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable()
viewModels.sortedByDescending { it.subscriptionId == activeSubId }
}
- val dualSim: DualSim? by
+ override val dualSim: DualSim? by
hydrator.hydratedStateOf(
traceName = "dualSim",
source =
@@ -68,7 +81,7 @@ constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable()
initialValue = null,
)
- val networkTypeIcon: Icon.Resource? by
+ override val networkTypeIcon: Icon.Resource? by
hydrator.hydratedStateOf(
traceName = "networkTypeIcon",
source =
@@ -78,7 +91,7 @@ constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable()
initialValue = null,
)
- val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
+ override val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
override suspend fun onActivated(): Nothing {
hydrator.activate()
@@ -86,11 +99,6 @@ constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable()
@AssistedFactory
interface Factory {
- fun create(): StackedMobileIconViewModel
+ fun create(): StackedMobileIconViewModelImpl
}
-
- data class DualSim(
- val primary: SignalIconModel.Cellular,
- val secondary: SignalIconModel.Cellular,
- )
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
index 2dbb02c8f095..402fdf03941d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
@@ -16,81 +16,71 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
-import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import com.android.systemui.KairosBuilder
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.lifecycle.ExclusiveActivatable
-import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel.DualSim
+import com.android.systemui.util.composable.kairos.hydratedComposeStateOf
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
class StackedMobileIconViewModelKairos
@AssistedInject
-constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable() {
- private val hydrator = Hydrator("StackedMobileIconViewModel")
+constructor(mobileIcons: MobileIconsViewModelKairos) :
+ KairosBuilder by kairosBuilder(), StackedMobileIconViewModel {
private val isStackable: Boolean by
- hydrator.hydratedStateOf(
- traceName = "isStackable",
- source = mobileIconsViewModel.isStackable,
- initialValue = false,
- )
+ hydratedComposeStateOf(mobileIcons.isStackable, initialValue = false)
- private val iconViewModelFlow: Flow<List<MobileIconViewModelCommon>> =
- combine(
- mobileIconsViewModel.mobileSubViewModels,
- mobileIconsViewModel.activeMobileDataSubscriptionId,
- ) { viewModels, activeSubId ->
- // Sort to get the active subscription first, if it's set
- viewModels.sortedByDescending { it.subscriptionId == activeSubId }
+ private val iconList: KairosState<List<MobileIconViewModelKairos>> =
+ combine(mobileIcons.icons, mobileIcons.activeSubscriptionId) { iconsBySubId, activeSubId ->
+ buildList {
+ activeSubId?.let { iconsBySubId[activeSubId]?.let { add(it) } }
+ addAll(iconsBySubId.values.asSequence().filter { it.subscriptionId != activeSubId })
+ }
}
- val dualSim: DualSim? by
- hydrator.hydratedStateOf(
- traceName = "dualSim",
- source =
- iconViewModelFlow.flatMapLatest { viewModels ->
- combine(viewModels.map { it.icon }) { icons ->
- icons
- .toList()
- .filterIsInstance<SignalIconModel.Cellular>()
- .takeIf { it.size == 2 }
- ?.let { DualSim(it[0], it[1]) }
- }
- },
+ override val dualSim: DualSim? by
+ hydratedComposeStateOf(
+ iconList.flatMap { icons ->
+ icons.map { it.icon }.combine { signalIcons -> tryParseDualSim(signalIcons) }
+ },
initialValue = null,
)
- val networkTypeIcon: Icon.Resource? by
- hydrator.hydratedStateOf(
- traceName = "networkTypeIcon",
- source =
- iconViewModelFlow.flatMapLatest { viewModels ->
- viewModels.firstOrNull()?.networkTypeIcon ?: flowOf(null)
- },
+ override val networkTypeIcon: Icon.Resource? by
+ hydratedComposeStateOf(
+ iconList.flatMap { icons -> icons.firstOrNull()?.networkTypeIcon ?: stateOf(null) },
initialValue = null,
)
- val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
+ override val isIconVisible: Boolean
+ get() = isStackable && dualSim != null
- override suspend fun onActivated(): Nothing {
- hydrator.activate()
+ private fun tryParseDualSim(icons: List<SignalIconModel>): DualSim? {
+ var first: SignalIconModel.Cellular? = null
+ var second: SignalIconModel.Cellular? = null
+ for (icon in icons) {
+ when {
+ icon !is SignalIconModel.Cellular -> continue
+ first == null -> first = icon
+ second == null -> second = icon
+ else -> return null
+ }
+ }
+ return first?.let { second?.let { DualSim(first, second) } }
}
@AssistedFactory
interface Factory {
fun create(): StackedMobileIconViewModelKairos
}
-
- data class DualSim(
- val primary: SignalIconModel.Cellular,
- val secondary: SignalIconModel.Cellular,
- )
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
index a791376a48d5..38ac5e6be2e1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
@@ -26,7 +26,6 @@ import android.os.SystemClock;
*/
public class AlarmTimeout implements AlarmManager.OnAlarmListener {
- public static final int MODE_CRASH_IF_SCHEDULED = 0;
public static final int MODE_IGNORE_IF_SCHEDULED = 1;
public static final int MODE_RESCHEDULE_IF_SCHEDULED = 2;
@@ -48,17 +47,11 @@ public class AlarmTimeout implements AlarmManager.OnAlarmListener {
* Schedules an alarm in {@code timeout} milliseconds in the future.
*
* @param timeout How long to wait from now.
- * @param mode {@link #MODE_CRASH_IF_SCHEDULED}, {@link #MODE_IGNORE_IF_SCHEDULED} or
- * {@link #MODE_RESCHEDULE_IF_SCHEDULED}.
+ * @param mode {@link #MODE_IGNORE_IF_SCHEDULED} or {@link #MODE_RESCHEDULE_IF_SCHEDULED}.
* @return {@code true} when scheduled successfully, {@code false} otherwise.
*/
public boolean schedule(long timeout, int mode) {
switch (mode) {
- case MODE_CRASH_IF_SCHEDULED:
- if (mScheduled) {
- throw new IllegalStateException(mTag + " timeout is already scheduled");
- }
- break;
case MODE_IGNORE_IF_SCHEDULED:
if (mScheduled) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt b/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt
new file mode 100644
index 000000000000..0d53a001f3f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.composable.kairos
+
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.KairosBuilder
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+
+@ExperimentalKairosApi
+fun <T> KairosBuilder.hydratedComposeStateOf(
+ source: State<T>,
+ initialValue: T,
+): androidx.compose.runtime.State<T> =
+ mutableStateOf(initialValue).also { state ->
+ onActivated { source.observe { state.value = it } }
+ }
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 32f784f17bb7..db4b8ef5aef7 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
@@ -17,42 +17,37 @@
package com.android.systemui.volume.dialog.sliders.ui
import android.view.View
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.interaction.DragInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SliderDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.theme.PlatformTheme
-import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
-import com.android.systemui.volume.dialog.sliders.ui.compose.VolumeDialogSliderTrack
+import com.android.systemui.volume.dialog.sliders.ui.compose.SliderTrack
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogOverscrollViewModel
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
-import com.android.systemui.volume.ui.slider.AccessibilityParams
-import com.android.systemui.volume.ui.slider.Haptics
-import com.android.systemui.volume.ui.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.AccessibilityParams
+import com.android.systemui.volume.ui.compose.slider.Haptics
+import com.android.systemui.volume.ui.compose.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.SliderIcon
import javax.inject.Inject
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.currentCoroutineContext
@@ -85,7 +80,7 @@ constructor(
}
}
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
private fun VolumeDialogSlider(
viewModel: VolumeDialogSliderViewModel,
@@ -95,10 +90,7 @@ private fun VolumeDialogSlider(
) {
val colors =
SliderDefaults.colors(
- thumbColor = MaterialTheme.colorScheme.primary,
activeTickColor = MaterialTheme.colorScheme.surfaceContainerHighest,
- inactiveTickColor = MaterialTheme.colorScheme.primary,
- activeTrackColor = MaterialTheme.colorScheme.primary,
inactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest,
)
val collectedSliderStateModel by viewModel.state.collectAsStateWithLifecycle(null)
@@ -142,18 +134,38 @@ private fun VolumeDialogSlider(
} ?: Haptics.Disabled,
stepDistance = 1f,
track = { sliderState ->
- VolumeDialogSliderTrack(
+ SliderTrack(
sliderState,
colors = colors,
isEnabled = !sliderStateModel.isDisabled,
- activeTrackEndIcon = { iconsState ->
- VolumeIcon(sliderStateModel.icon, iconsState.isActiveTrackEndIconVisible)
+ isVertical = true,
+ activeTrackStartIcon = { iconsState ->
+ SliderIcon(
+ icon = {
+ Icon(icon = sliderStateModel.icon, modifier = Modifier.size(20.dp))
+ },
+ isVisible = iconsState.isActiveTrackStartIconVisible,
+ )
},
- inactiveTrackEndIcon = { iconsState ->
- VolumeIcon(sliderStateModel.icon, !iconsState.isActiveTrackEndIconVisible)
+ inactiveTrackStartIcon = { iconsState ->
+ SliderIcon(
+ icon = {
+ Icon(icon = sliderStateModel.icon, modifier = Modifier.size(20.dp))
+ },
+ isVisible = !iconsState.isActiveTrackStartIconVisible,
+ )
},
)
},
+ thumb = { sliderState, interactions ->
+ SliderDefaults.Thumb(
+ sliderState = sliderState,
+ interactionSource = interactions,
+ enabled = !sliderStateModel.isDisabled,
+ colors = colors,
+ thumbSize = DpSize(52.dp, 4.dp),
+ )
+ },
accessibilityParams = AccessibilityParams(contentDescription = sliderStateModel.label),
modifier =
modifier.pointerInput(Unit) {
@@ -168,19 +180,3 @@ private fun VolumeDialogSlider(
},
)
}
-
-@Composable
-private fun BoxScope.VolumeIcon(
- icon: Icon.Loaded,
- isVisible: Boolean,
- modifier: Modifier = Modifier,
-) {
- AnimatedVisibility(
- visible = isVisible,
- enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)),
- exit = fadeOut(animationSpec = tween(durationMillis = 50)),
- modifier = modifier.align(Alignment.Center).size(40.dp).padding(10.dp),
- ) {
- Icon(icon)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
index 1dd9ddac79be..fb8de45bfad1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
@@ -19,6 +19,7 @@ package com.android.systemui.volume.dialog.sliders.ui.compose
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
@@ -32,38 +33,47 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.util.fastFilter
import androidx.compose.ui.util.fastFirst
import kotlin.math.min
@Composable
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
-fun VolumeDialogSliderTrack(
+fun SliderTrack(
sliderState: SliderState,
- colors: SliderColors,
isEnabled: Boolean,
modifier: Modifier = Modifier,
+ colors: SliderColors = SliderDefaults.colors(),
thumbTrackGapSize: Dp = 6.dp,
trackCornerSize: Dp = 12.dp,
trackInsideCornerSize: Dp = 2.dp,
trackSize: Dp = 40.dp,
+ isVertical: Boolean = false,
activeTrackStartIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
activeTrackEndIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
inactiveTrackStartIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
inactiveTrackEndIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
) {
- val measurePolicy = remember(sliderState) { TrackMeasurePolicy(sliderState) }
+ val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
+ val measurePolicy =
+ remember(sliderState) {
+ TrackMeasurePolicy(
+ sliderState = sliderState,
+ shouldMirrorIcons = !isVertical && isRtl || isVertical,
+ isVertical = isVertical,
+ gapSize = thumbTrackGapSize,
+ )
+ }
Layout(
measurePolicy = measurePolicy,
content = {
@@ -76,33 +86,41 @@ fun VolumeDialogSliderTrack(
drawStopIndicator = null,
thumbTrackGapSize = thumbTrackGapSize,
drawTick = { _, _ -> },
- modifier = Modifier.width(trackSize).layoutId(Contents.Track),
+ modifier =
+ Modifier.then(
+ if (isVertical) {
+ Modifier.width(trackSize)
+ } else {
+ Modifier.height(trackSize)
+ }
+ )
+ .layoutId(Contents.Track),
)
TrackIcon(
icon = activeTrackStartIcon,
- contentsId = Contents.Active.TrackStartIcon,
+ contents = Contents.Active.TrackStartIcon,
isEnabled = isEnabled,
colors = colors,
state = measurePolicy,
)
TrackIcon(
icon = activeTrackEndIcon,
- contentsId = Contents.Active.TrackEndIcon,
+ contents = Contents.Active.TrackEndIcon,
isEnabled = isEnabled,
colors = colors,
state = measurePolicy,
)
TrackIcon(
icon = inactiveTrackStartIcon,
- contentsId = Contents.Inactive.TrackStartIcon,
+ contents = Contents.Inactive.TrackStartIcon,
isEnabled = isEnabled,
colors = colors,
state = measurePolicy,
)
TrackIcon(
icon = inactiveTrackEndIcon,
- contentsId = Contents.Inactive.TrackEndIcon,
+ contents = Contents.Inactive.TrackEndIcon,
isEnabled = isEnabled,
colors = colors,
state = measurePolicy,
@@ -116,24 +134,47 @@ fun VolumeDialogSliderTrack(
private fun TrackIcon(
icon: (@Composable BoxScope.(sliderIconsState: SliderIconsState) -> Unit)?,
isEnabled: Boolean,
- contentsId: Contents,
+ contents: Contents,
state: SliderIconsState,
colors: SliderColors,
modifier: Modifier = Modifier,
) {
icon ?: return
- Box(modifier = modifier.layoutId(contentsId).fillMaxSize()) {
- CompositionLocalProvider(
- LocalContentColor provides contentsId.getColor(colors, isEnabled)
- ) {
- icon(state)
+ /*
+ ignore icons mirroring for the rtl layouts here because icons positioning is handled by the
+ TrackMeasurePolicy. It ensures that active icons are always above the active track and the
+ same for inactive
+ */
+ val iconColor =
+ when (contents) {
+ is Contents.Inactive ->
+ if (isEnabled) {
+ colors.inactiveTickColor
+ } else {
+ colors.disabledInactiveTickColor
+ }
+ is Contents.Active ->
+ if (isEnabled) {
+ colors.activeTickColor
+ } else {
+ colors.disabledActiveTickColor
+ }
+ is Contents.Track -> {
+ error("$contents is unsupported by the TrackIcon")
+ }
}
+ Box(modifier = modifier.layoutId(contents).fillMaxSize()) {
+ CompositionLocalProvider(LocalContentColor provides iconColor) { icon(state) }
}
}
@OptIn(ExperimentalMaterial3Api::class)
-private class TrackMeasurePolicy(private val sliderState: SliderState) :
- MeasurePolicy, SliderIconsState {
+private class TrackMeasurePolicy(
+ private val sliderState: SliderState,
+ private val shouldMirrorIcons: Boolean,
+ private val gapSize: Dp,
+ private val isVertical: Boolean,
+) : MeasurePolicy, SliderIconsState {
private val isVisible: Map<Contents, MutableState<Boolean>> =
mutableMapOf(
@@ -144,16 +185,16 @@ private class TrackMeasurePolicy(private val sliderState: SliderState) :
)
override val isActiveTrackStartIconVisible: Boolean
- get() = isVisible.getValue(Contents.Active.TrackStartIcon).value
+ get() = isVisible.getValue(Contents.Active.TrackStartIcon.resolve()).value
override val isActiveTrackEndIconVisible: Boolean
- get() = isVisible.getValue(Contents.Active.TrackEndIcon).value
+ get() = isVisible.getValue(Contents.Active.TrackEndIcon.resolve()).value
override val isInactiveTrackStartIconVisible: Boolean
- get() = isVisible.getValue(Contents.Inactive.TrackStartIcon).value
+ get() = isVisible.getValue(Contents.Inactive.TrackStartIcon.resolve()).value
override val isInactiveTrackEndIconVisible: Boolean
- get() = isVisible.getValue(Contents.Inactive.TrackEndIcon).value
+ get() = isVisible.getValue(Contents.Inactive.TrackEndIcon.resolve()).value
override fun MeasureScope.measure(
measurables: List<Measurable>,
@@ -164,178 +205,196 @@ private class TrackMeasurePolicy(private val sliderState: SliderState) :
val iconSize = min(track.width, track.height)
val iconConstraints = constraints.copy(maxWidth = iconSize, maxHeight = iconSize)
- val icons =
- measurables
- .fastFilter { it.layoutId != Contents.Track }
- .associateBy(
- keySelector = { it.layoutId as Contents },
- valueTransform = { it.measure(iconConstraints) },
- )
-
- return layout(track.width, track.height) {
- with(Contents.Track) {
- performPlacing(
- placeable = track,
- width = track.width,
- height = track.height,
- sliderState = sliderState,
- )
+ val components = buildMap {
+ put(Contents.Track, track)
+ for (measurable in measurables) {
+ // don't measure track a second time
+ if (measurable.layoutId != Contents.Track) {
+ put(
+ (measurable.layoutId as Contents).resolve(),
+ measurable.measure(iconConstraints),
+ )
+ }
}
+ }
- for (iconLayoutId in icons.keys) {
- with(iconLayoutId) {
- performPlacing(
- placeable = icons.getValue(iconLayoutId),
- width = track.width,
- height = track.height,
- sliderState = sliderState,
+ return layout(track.width, track.height) {
+ val gapSizePx = gapSize.roundToPx()
+ val coercedValueAsFraction =
+ if (shouldMirrorIcons) {
+ 1 - sliderState.coercedValueAsFraction
+ } else {
+ sliderState.coercedValueAsFraction
+ }
+ for (iconLayoutId in components.keys) {
+ val iconPlaceable = components.getValue(iconLayoutId)
+ if (isVertical) {
+ iconPlaceable.place(
+ 0,
+ iconLayoutId.calculatePosition(
+ placeableDimension = iconPlaceable.height,
+ containerDimension = track.height,
+ gapSize = gapSizePx,
+ coercedValueAsFraction = coercedValueAsFraction,
+ ),
+ )
+ } else {
+ iconPlaceable.place(
+ iconLayoutId.calculatePosition(
+ placeableDimension = iconPlaceable.width,
+ containerDimension = track.width,
+ gapSize = gapSizePx,
+ coercedValueAsFraction = coercedValueAsFraction,
+ ),
+ 0,
)
+ }
- isVisible.getValue(iconLayoutId).value =
- isVisible(
- placeable = icons.getValue(iconLayoutId),
- width = track.width,
- height = track.height,
- sliderState = sliderState,
+ // isVisible is only relevant for the icons
+ if (iconLayoutId != Contents.Track) {
+ val isVisibleState = isVisible.getValue(iconLayoutId)
+ val newIsVisible =
+ iconLayoutId.isVisible(
+ placeableDimension =
+ if (isVertical) iconPlaceable.height else iconPlaceable.width,
+ containerDimension = if (isVertical) track.height else track.width,
+ gapSize = gapSizePx,
+ coercedValueAsFraction = coercedValueAsFraction,
)
+ if (isVisibleState.value != newIsVisible) {
+ isVisibleState.value = newIsVisible
+ }
}
}
}
}
+
+ private fun Contents.resolve(): Contents {
+ return if (shouldMirrorIcons) {
+ mirrored
+ } else {
+ this
+ }
+ }
}
-@OptIn(ExperimentalMaterial3Api::class)
private sealed interface Contents {
data object Track : Contents {
- override fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) = placeable.place(x = 0, y = 0)
+
+ override val mirrored: Contents
+ get() = error("unsupported for Track")
+
+ override fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int = 0
override fun isVisible(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) = true
-
- override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color =
- error("Unsupported")
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Boolean = true
}
interface Active : Contents {
- override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color {
- return if (isEnabled) {
- sliderColors.activeTickColor
- } else {
- sliderColors.disabledActiveTickColor
- }
- }
+
+ override fun isVisible(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Boolean =
+ (containerDimension * coercedValueAsFraction - gapSize).toInt() > placeableDimension
data object TrackStartIcon : Active {
- override fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) =
- placeable.place(
- x = 0,
- y = (height * (1 - sliderState.coercedValueAsFraction)).toInt(),
- )
-
- override fun isVisible(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ): Boolean = (height * (sliderState.coercedValueAsFraction)).toInt() > placeable.height
+
+ override val mirrored: Contents
+ get() = Inactive.TrackEndIcon
+
+ override fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int = 0
}
data object TrackEndIcon : Active {
- override fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) = placeable.place(x = 0, y = (height - placeable.height))
-
- override fun isVisible(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ): Boolean = (height * (sliderState.coercedValueAsFraction)).toInt() > placeable.height
+
+ override val mirrored: Contents
+ get() = Inactive.TrackStartIcon
+
+ override fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int =
+ (containerDimension * coercedValueAsFraction - placeableDimension - gapSize).toInt()
}
}
interface Inactive : Contents {
- override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color {
- return if (isEnabled) {
- sliderColors.inactiveTickColor
- } else {
- sliderColors.disabledInactiveTickColor
- }
- }
+ override fun isVisible(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Boolean =
+ containerDimension - (containerDimension * coercedValueAsFraction + gapSize) >
+ placeableDimension
data object TrackStartIcon : Inactive {
- override fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) {
- placeable.place(x = 0, y = 0)
- }
- override fun isVisible(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ): Boolean =
- (height * (1 - sliderState.coercedValueAsFraction)).toInt() > placeable.height
+ override val mirrored: Contents
+ get() = Active.TrackEndIcon
+
+ override fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int = (containerDimension * coercedValueAsFraction + gapSize).toInt()
}
data object TrackEndIcon : Inactive {
- override fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ) {
- placeable.place(
- x = 0,
- y =
- (height * (1 - sliderState.coercedValueAsFraction)).toInt() -
- placeable.height,
- )
- }
- override fun isVisible(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- ): Boolean =
- (height * (1 - sliderState.coercedValueAsFraction)).toInt() > placeable.height
+ override val mirrored: Contents
+ get() = Active.TrackStartIcon
+
+ override fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int = containerDimension - placeableDimension
}
}
- fun Placeable.PlacementScope.performPlacing(
- placeable: Placeable,
- width: Int,
- height: Int,
- sliderState: SliderState,
- )
-
- fun isVisible(placeable: Placeable, width: Int, height: Int, sliderState: SliderState): Boolean
-
- fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color
+ fun calculatePosition(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Int
+
+ fun isVisible(
+ placeableDimension: Int,
+ containerDimension: Int,
+ gapSize: Int,
+ coercedValueAsFraction: Float,
+ ): Boolean
+
+ /**
+ * [Contents] that is visually on the opposite side of the current one on the slider. This is
+ * handy when dealing with the rtl layouts
+ */
+ val mirrored: Contents
}
/** Provides visibility state for each of the Slider's icons. */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt
index 502b311f7b40..54d2f79509c3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt
@@ -16,7 +16,7 @@
@file:OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
-package com.android.systemui.volume.ui.slider
+package com.android.systemui.volume.ui.compose.slider
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
@@ -61,8 +61,6 @@ import kotlinx.coroutines.launch
private val defaultSpring =
SpringSpec<Float>(dampingRatio = Spring.DampingRatioNoBouncy, stiffness = Spring.StiffnessHigh)
-private val defaultTrack: @Composable (SliderState) -> Unit =
- @Composable { SliderDefaults.Track(it) }
@Composable
fun Slider(
@@ -79,7 +77,14 @@ fun Slider(
haptics: Haptics = Haptics.Disabled,
isVertical: Boolean = false,
isReverseDirection: Boolean = false,
- track: (@Composable (SliderState) -> Unit)? = null,
+ track: (@Composable (SliderState) -> Unit) = { SliderDefaults.Track(it) },
+ thumb: (@Composable (SliderState, MutableInteractionSource) -> Unit) = { _, _ ->
+ SliderDefaults.Thumb(
+ interactionSource = interactionSource,
+ colors = colors,
+ enabled = isEnabled,
+ )
+ },
) {
require(stepDistance >= 0) { "stepDistance must not be negative" }
val coroutineScope = rememberCoroutineScope()
@@ -139,7 +144,8 @@ fun Slider(
reverseDirection = isReverseDirection,
interactionSource = interactionSource,
colors = colors,
- track = track ?: defaultTrack,
+ track = track,
+ thumb = { thumb(it, interactionSource) },
modifier = modifier.clearAndSetSemantics(semantics),
)
} else {
@@ -148,7 +154,8 @@ fun Slider(
enabled = isEnabled,
interactionSource = interactionSource,
colors = colors,
- track = track ?: defaultTrack,
+ track = track,
+ thumb = { thumb(it, interactionSource) },
modifier = modifier.clearAndSetSemantics(semantics),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt
new file mode 100644
index 000000000000..fd8f47794fc0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.ui.compose.slider
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+
+@Composable
+fun SliderIcon(
+ icon: @Composable BoxScope.() -> Unit,
+ isVisible: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) {
+ AnimatedVisibility(
+ visible = isVisible,
+ enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)),
+ exit = fadeOut(animationSpec = tween(durationMillis = 50)),
+ ) {
+ icon()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/window/data/repository/NoopWindowRootViewBlurRepository.kt b/packages/SystemUI/src/com/android/systemui/window/data/repository/NoopWindowRootViewBlurRepository.kt
index f1dd374d3e1d..1ae8bc9405dc 100644
--- a/packages/SystemUI/src/com/android/systemui/window/data/repository/NoopWindowRootViewBlurRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/data/repository/NoopWindowRootViewBlurRepository.kt
@@ -16,13 +16,12 @@
package com.android.systemui.window.data.repository
-import com.android.systemui.window.data.repository.WindowRootViewBlurRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class NoopWindowRootViewBlurRepository @Inject constructor() : WindowRootViewBlurRepository {
- override val blurRadius: MutableStateFlow<Int> = MutableStateFlow(0)
+ override val blurRequestedByShade: MutableStateFlow<Int> = MutableStateFlow(0)
override val isBlurOpaque: MutableStateFlow<Boolean> = MutableStateFlow(true)
override val isBlurSupported: StateFlow<Boolean> = MutableStateFlow(false)
override var blurAppliedListener: BlurAppliedListener? = null
diff --git a/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt b/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt
index f98efe1e3c33..9b934bc6c866 100644
--- a/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt
@@ -39,7 +39,7 @@ typealias BlurAppliedListener = Consumer<Int>
/** Repository that maintains state for the window blur effect. */
interface WindowRootViewBlurRepository {
- val blurRadius: MutableStateFlow<Int>
+ val blurRequestedByShade: MutableStateFlow<Int>
val isBlurOpaque: MutableStateFlow<Boolean>
/** Is blur supported based on settings toggle and battery power saver mode. */
@@ -67,7 +67,7 @@ constructor(
@Main private val executor: Executor,
@Application private val scope: CoroutineScope,
) : WindowRootViewBlurRepository {
- override val blurRadius = MutableStateFlow(0)
+ override val blurRequestedByShade = MutableStateFlow(0)
override val isBlurOpaque = MutableStateFlow(false)
diff --git a/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt b/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt
index 5197242e8079..2994138f8181 100644
--- a/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt
@@ -87,7 +87,7 @@ constructor(
val isBlurCurrentlySupported: StateFlow<Boolean> = repository.isBlurSupported
/** Radius of blur to be applied on the window root view. */
- val blurRadius: StateFlow<Int> = repository.blurRadius.asStateFlow()
+ val blurRadiusRequestedByShade: StateFlow<Int> = repository.blurRequestedByShade.asStateFlow()
/** Whether the blur applied is opaque or transparent. */
val isBlurOpaque: Flow<Boolean> =
@@ -128,7 +128,7 @@ constructor(
return false
}
Log.d(TAG, "requestingBlurForShade for $blurRadius $opaque")
- repository.blurRadius.value = blurRadius
+ repository.blurRequestedByShade.value = blurRadius
repository.isBlurOpaque.value = opaque
return true
}
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
index 06532bc0cc2a..fd642f99ef54 100644
--- a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
@@ -59,6 +59,15 @@ object WindowRootViewBinder {
) { viewModel ->
try {
Log.d(TAG, "Launching coroutines that update window root view state")
+ launchTraced("early-wakeup") {
+ viewModel.isPersistentEarlyWakeupRequired.collect { wakeupRequired ->
+ blurUtils.setPersistentEarlyWakeup(
+ wakeupRequired,
+ view.rootView?.viewRootImpl,
+ )
+ }
+ }
+
launchTraced("WindowBlur") {
var wasUpdateScheduledForThisFrame = false
var lastScheduledBlurRadius = 0
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
index e60e85335f7a..89101c961031 100644
--- a/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
@@ -19,13 +19,16 @@ package com.android.systemui.window.ui.viewmodel
import android.os.Build
import android.util.Log
import com.android.systemui.Flags
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
@@ -41,6 +44,8 @@ constructor(
primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>,
glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>,
private val blurInteractor: WindowRootViewBlurInteractor,
+ private val keyguardInteractor: KeyguardInteractor,
+ private val shadeInteractor: ShadeInteractor,
) {
private val bouncerBlurRadiusFlows =
@@ -57,7 +62,9 @@ constructor(
listOf(
*bouncerBlurRadiusFlows.toTypedArray(),
*glanceableHubBlurRadiusFlows.toTypedArray(),
- blurInteractor.blurRadius.map { it.toFloat() }.logIfPossible("ShadeBlur"),
+ blurInteractor.blurRadiusRequestedByShade
+ .map { it.toFloat() }
+ .logIfPossible("ShadeBlur"),
)
.merge()
@@ -70,6 +77,24 @@ constructor(
}
}
+ val isPersistentEarlyWakeupRequired =
+ blurInteractor.isBlurCurrentlySupported
+ .flatMapLatest { blurSupported ->
+ if (blurSupported) {
+ combine(
+ keyguardInteractor.isKeyguardShowing,
+ shadeInteractor.isUserInteracting,
+ shadeInteractor.isAnyExpanded,
+ ) { keyguardShowing, userDraggingShade, anyExpanded ->
+ keyguardShowing || userDraggingShade || anyExpanded
+ }
+ } else {
+ flowOf(false)
+ }
+ }
+ .distinctUntilChanged()
+ .logIfPossible("isPersistentEarlyWakeupRequired")
+
val isBlurOpaque =
blurInteractor.isBlurCurrentlySupported.flatMapLatest { blurSupported ->
if (blurSupported) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 8105ae0960ad..206654abcaaa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -101,7 +101,6 @@ import com.android.systemui.dreams.ui.viewmodel.DreamViewModel;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.SystemPropertiesHelper;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionBootInteractor;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.log.SessionTracker;
@@ -207,7 +206,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock ShadeWindowLogger mShadeWindowLogger;
private @Mock SelectedUserInteractor mSelectedUserInteractor;
private @Mock UserTracker.Callback mUserTrackerCallback;
- private @Mock KeyguardInteractor mKeyguardInteractor;
private @Mock KeyguardTransitionBootInteractor mKeyguardTransitionBootInteractor;
private @Captor ArgumentCaptor<KeyguardStateController.Callback>
mKeyguardStateControllerCallback;
@@ -1499,7 +1497,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mSystemPropertiesHelper,
() -> mock(WindowManagerLockscreenVisibilityManager.class),
mSelectedUserInteractor,
- mKeyguardInteractor,
+ mKosmos.getKeyguardInteractor(),
mKeyguardTransitionBootInteractor,
mKosmos::getCommunalSceneInteractor,
mock(WindowManagerOcclusionManager.class));
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
index ff4ba61b6965..208eabc44073 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
@@ -16,11 +16,13 @@
package com.android.systemui.display.data.repository
+import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
+import kotlinx.coroutines.CoroutineScope
val Kosmos.fakeDisplayScopeRepository by
Kosmos.Fixture { FakeDisplayScopeRepository(testDispatcher) }
-var Kosmos.displayScopeRepository: DisplayScopeRepository by
+var Kosmos.displayScopeRepository: PerDisplayRepository<CoroutineScope> by
Kosmos.Fixture { fakeDisplayScopeRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
index 3c2592471694..84c9abfba803 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
@@ -16,15 +16,18 @@
package com.android.systemui.display.data.repository
+import com.android.app.displaylib.PerDisplayRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
-class FakeDisplayScopeRepository(private val dispatcher: CoroutineDispatcher) :
- DisplayScopeRepository {
+class FakeDisplayScopeRepository(
+ private val dispatcher: CoroutineDispatcher,
+ override val debugName: String = "FakeDisplayScopeRepository",
+) : PerDisplayRepository<CoroutineScope> {
private val perDisplayScopes = mutableMapOf<Int, CoroutineScope>()
- override fun scopeForDisplay(displayId: Int): CoroutineScope {
+ override fun get(displayId: Int): CoroutineScope {
return perDisplayScopes.computeIfAbsent(displayId) { CoroutineScope(dispatcher) }
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
index 4b516e9c74bc..161e06295852 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
@@ -16,6 +16,8 @@
package com.android.systemui.display.data.repository
+import com.android.app.displaylib.DisplayInstanceLifecycleManager
+import com.android.app.displaylib.FakeDisplayInstanceLifecycleManager
import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown
import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
import com.android.systemui.dump.dumpManager
@@ -69,13 +71,25 @@ val Kosmos.fakePerDisplayInstanceProviderWithTeardown by
Kosmos.Fixture { FakePerDisplayInstanceProviderWithTeardown() }
val Kosmos.perDisplayDumpHelper by Kosmos.Fixture { PerDisplayRepoDumpHelper(dumpManager) }
+val Kosmos.fakeDisplayInstanceLifecycleManager by
+ Kosmos.Fixture { FakeDisplayInstanceLifecycleManager() }
+
val Kosmos.fakePerDisplayInstanceRepository by
Kosmos.Fixture {
- PerDisplayInstanceRepositoryImpl(
- debugName = "fakePerDisplayInstanceRepository",
- instanceProvider = fakePerDisplayInstanceProviderWithTeardown,
- testScope.backgroundScope,
- displayRepository,
- perDisplayDumpHelper,
- )
+ { lifecycleManager: DisplayInstanceLifecycleManager? ->
+ PerDisplayInstanceRepositoryImpl(
+ debugName = "fakePerDisplayInstanceRepository",
+ instanceProvider = fakePerDisplayInstanceProviderWithTeardown,
+ lifecycleManager,
+ testScope.backgroundScope,
+ displayRepository,
+ perDisplayDumpHelper,
+ )
+ }
}
+
+fun Kosmos.createPerDisplayInstanceRepository(
+ overrideLifecycleManager: DisplayInstanceLifecycleManager? = null
+): PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> {
+ return fakePerDisplayInstanceRepository(overrideLifecycleManager)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
index dc22905ba320..56fd270dffb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
@@ -18,5 +18,11 @@ package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
-val Kosmos.detailsViewModel by Kosmos.Fixture { DetailsViewModel(currentTilesInteractor) }
+val Kosmos.detailsViewModel by Kosmos.Fixture {
+ DetailsViewModel(
+ currentTilesInteractor,
+ shadeModeInteractor
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
index 63085e178e7d..165f85d2cbba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
@@ -29,6 +29,8 @@ fun activeNotificationModel(
key: String,
groupKey: String? = null,
whenTime: Long = 0L,
+ isForegroundService: Boolean = false,
+ isOngoingEvent: Boolean = false,
isAmbient: Boolean = false,
isRowDismissed: Boolean = false,
isSilent: Boolean = false,
@@ -53,6 +55,8 @@ fun activeNotificationModel(
key = key,
groupKey = groupKey,
whenTime = whenTime,
+ isForegroundService = isForegroundService,
+ isOngoingEvent = isOngoingEvent,
isAmbient = isAmbient,
isRowDismissed = isRowDismissed,
isSilent = isSilent,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt
index 093ec10e2642..8b2c68aa04cd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorKosmos.kt
@@ -19,13 +19,17 @@ package com.android.systemui.statusbar.notification.promoted.domain.interactor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.statusbar.chips.call.domain.interactor.callChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
+import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.screenRecordChipInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
val Kosmos.promotedNotificationsInteractor by
Kosmos.Fixture {
PromotedNotificationsInteractor(
activeNotificationsInteractor = activeNotificationsInteractor,
+ screenRecordChipInteractor = screenRecordChipInteractor,
+ mediaProjectionChipInteractor = mediaProjectionChipInteractor,
callChipInteractor = callChipInteractor,
notifChipsInteractor = statusBarNotificationChipsInteractor,
backgroundDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/AppIconProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/AppIconProviderKosmos.kt
index 0fd0f1469818..277fc62242b1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/AppIconProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/AppIconProviderKosmos.kt
@@ -19,6 +19,9 @@ package com.android.systemui.statusbar.notification.row.icon
import android.content.applicationContext
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+val Kosmos.mockAppIconProvider by Kosmos.Fixture { mock<AppIconProvider>() }
val Kosmos.appIconProvider by
Kosmos.Fixture { AppIconProviderImpl(applicationContext, dumpManager) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt
index b4fb7dd9d760..86ff722f99be 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt
@@ -19,6 +19,10 @@ package com.android.systemui.statusbar.notification.row.icon
import android.os.userManager
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+val Kosmos.mockNotificationIconStyleProvider by
+ Kosmos.Fixture { mock<NotificationIconStyleProvider>() }
val Kosmos.notificationIconStyleProvider by
Kosmos.Fixture { NotificationIconStyleProviderImpl(userManager, dumpManager) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt
new file mode 100644
index 000000000000..83b8283b1892
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
+
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.ui.mobileViewLogger
+import com.android.systemui.util.mockito.mock
+
+@ExperimentalKairosApi
+val Kosmos.mobileIconsViewModelKairos by ActivatedKairosFixture {
+ MobileIconsViewModelKairos(
+ logger = mobileViewLogger,
+ verboseLogger = mock(),
+ interactor = mobileIconsInteractorKairos,
+ airplaneModeInteractor = airplaneModeInteractor,
+ constants = mock(),
+ flags = featureFlagsClassic,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
index 3ee33802e9d5..ad42a89dc237 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
@@ -16,7 +16,11 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
import com.android.systemui.kosmos.Kosmos
-val Kosmos.stackedMobileIconViewModelKairos by
- Kosmos.Fixture { StackedMobileIconViewModelKairos(mobileIconsViewModel) }
+@ExperimentalKairosApi
+val Kosmos.stackedMobileIconViewModelKairos by ActivatedKairosFixture {
+ StackedMobileIconViewModelKairos(mobileIconsViewModelKairos)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
index 880ba5eee5d2..0a8e0a7d48b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
@@ -18,5 +18,8 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-val Kosmos.stackedMobileIconViewModel: StackedMobileIconViewModel by
- Kosmos.Fixture { StackedMobileIconViewModel(mobileIconsViewModel) }
+var Kosmos.stackedMobileIconViewModel: StackedMobileIconViewModel by
+ Kosmos.Fixture { stackedMobileIconViewModelImpl }
+
+val Kosmos.stackedMobileIconViewModelImpl by
+ Kosmos.Fixture { StackedMobileIconViewModelImpl(mobileIconsViewModel) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
index b619e2d70724..2b518182922d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
@@ -26,7 +26,7 @@ val Kosmos.windowRootViewBlurRepository: WindowRootViewBlurRepository by
Kosmos.Fixture { fakeWindowRootViewBlurRepository }
class FakeWindowRootViewBlurRepository : WindowRootViewBlurRepository {
- override val blurRadius: MutableStateFlow<Int> = MutableStateFlow(0)
+ override val blurRequestedByShade: MutableStateFlow<Int> = MutableStateFlow(0)
override val isBlurOpaque: MutableStateFlow<Boolean> = MutableStateFlow(false)
override val isBlurSupported: MutableStateFlow<Boolean> = MutableStateFlow(false)
override var blurAppliedListener: BlurAppliedListener? = null
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
index 5a02bfbacd35..e56f32f3534f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
@@ -16,9 +16,11 @@
package com.android.systemui.window.ui.viewmodel
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.ui.transitions.FakeBouncerTransition
import com.android.systemui.keyguard.ui.transitions.FakeGlanceableHubTransition
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
import org.mockito.internal.util.collections.Sets
@@ -38,5 +40,7 @@ val Kosmos.windowRootViewModel by
fakeBouncerTransitions,
fakeGlanceableHubTransitions,
windowRootViewBlurInteractor,
+ keyguardInteractor,
+ shadeInteractor,
)
}
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index b8e0d427f3d8..b0c0c3a5d455 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -48,7 +48,9 @@ android_test {
static_libs: [
"androidx.test.core",
"androidx.test.rules",
+ "flag-junit",
"mockito-target-minus-junit4",
+ "platform-test-annotations",
"truth",
],
resource_dirs: ["test/res"],
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 44ea9a2848ac..a80a64d6daba 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -16,6 +16,7 @@
package com.android.wallpaperbackup;
+import static android.app.Flags.liveWallpaperContentHandling;
import static android.app.WallpaperManager.FLAG_LOCK;
import static android.app.WallpaperManager.FLAG_SYSTEM;
import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
@@ -27,6 +28,7 @@ import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPE
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
import static com.android.window.flags.Flags.multiCrop;
+import android.annotation.Nullable;
import android.app.AppGlobals;
import android.app.WallpaperManager;
import android.app.backup.BackupAgent;
@@ -35,6 +37,7 @@ import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManager;
import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
@@ -493,11 +496,13 @@ public class WallpaperBackupAgent extends BackupAgent {
// First parse the live component name so that we know for logging if we care about
// logging errors with the image restore.
- ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
- mSystemHasLiveComponent = wpService != null;
+ Pair<ComponentName, WallpaperDescription> wpService = parseWallpaperComponent(infoStage,
+ "wp");
+ mSystemHasLiveComponent = wpService.first != null;
- ComponentName kwpService = parseWallpaperComponent(infoStage, "kwp");
- mLockHasLiveComponent = kwpService != null;
+ Pair<ComponentName, WallpaperDescription> kwpService = parseWallpaperComponent(
+ infoStage, "kwp");
+ mLockHasLiveComponent = kwpService.first != null;
boolean separateLockWallpaper = mLockHasLiveComponent || lockImageStage.exists();
// if there's no separate lock wallpaper, apply the system wallpaper to both screens.
@@ -586,25 +591,39 @@ public class WallpaperBackupAgent extends BackupAgent {
}
@VisibleForTesting
- void updateWallpaperComponent(ComponentName wpService, int which)
+ void updateWallpaperComponent(Pair<ComponentName, WallpaperDescription> wpService, int which)
throws IOException {
- if (servicePackageExists(wpService)) {
- Slog.i(TAG, "Using wallpaper service " + wpService);
- mWallpaperManager.setWallpaperComponentWithFlags(wpService, which);
- if ((which & FLAG_LOCK) != 0) {
- mEventLogger.onLockLiveWallpaperRestored(wpService);
- }
- if ((which & FLAG_SYSTEM) != 0) {
- mEventLogger.onSystemLiveWallpaperRestored(wpService);
+ WallpaperDescription description = wpService.second;
+ boolean hasDescription = (liveWallpaperContentHandling() && description != null);
+ ComponentName component = hasDescription ? description.getComponent() : wpService.first;
+ if (servicePackageExists(component)) {
+ if (hasDescription) {
+ Slog.i(TAG, "Using wallpaper description " + description);
+ mWallpaperManager.setWallpaperComponentWithDescription(description, which);
+ if ((which & FLAG_LOCK) != 0) {
+ mEventLogger.onLockLiveWallpaperRestoredWithDescription(description);
+ }
+ if ((which & FLAG_SYSTEM) != 0) {
+ mEventLogger.onSystemLiveWallpaperRestoredWithDescription(description);
+ }
+ } else {
+ Slog.i(TAG, "Using wallpaper service " + component);
+ mWallpaperManager.setWallpaperComponentWithFlags(component, which);
+ if ((which & FLAG_LOCK) != 0) {
+ mEventLogger.onLockLiveWallpaperRestored(component);
+ }
+ if ((which & FLAG_SYSTEM) != 0) {
+ mEventLogger.onSystemLiveWallpaperRestored(component);
+ }
}
} else {
// If we've restored a live wallpaper, but the component doesn't exist,
// we should log it as an error so we can easily identify the problem
// in reports from users
- if (wpService != null) {
+ if (component != null) {
// TODO(b/268471749): Handle delayed case
- applyComponentAtInstall(wpService, which);
- Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. "
+ applyComponentAtInstall(component, description, which);
+ Slog.w(TAG, "Wallpaper service " + component + " isn't available. "
+ " Will try to apply later");
}
}
@@ -697,7 +716,6 @@ public class WallpaperBackupAgent extends BackupAgent {
* (thereby preserving the center point). Then finally, adding any leftover image real-estate
* (i.e. space left over on the horizontal axis) to add parallax effect. Parallax is only added
* if was present in the old device's settings.
- *
*/
private Rect findNewCropfromOldCrop(Rect oldCrop, Point oldDisplaySize, boolean oldRtl,
Point newDisplaySize, Point bitmapSize, boolean newRtl) {
@@ -976,10 +994,12 @@ public class WallpaperBackupAgent extends BackupAgent {
return cropHints;
}
- private ComponentName parseWallpaperComponent(File wallpaperInfo, String sectionTag) {
+ private Pair<ComponentName, WallpaperDescription> parseWallpaperComponent(File wallpaperInfo,
+ String sectionTag) {
ComponentName name = null;
+ WallpaperDescription description = null;
try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
- final XmlPullParser parser = Xml.resolvePullParser(stream);
+ final TypedXmlPullParser parser = Xml.resolvePullParser(stream);
int type;
do {
@@ -991,6 +1011,7 @@ public class WallpaperBackupAgent extends BackupAgent {
name = (parsedName != null)
? ComponentName.unflattenFromString(parsedName)
: null;
+ description = parseWallpaperDescription(parser, name);
break;
}
}
@@ -998,9 +1019,30 @@ public class WallpaperBackupAgent extends BackupAgent {
} catch (Exception e) {
// Whoops; can't process the info file at all. Report failure.
Slog.w(TAG, "Failed to parse restored component: " + e.getMessage());
- return null;
+ return new Pair<>(null, null);
}
- return name;
+ return new Pair<>(name, description);
+ }
+
+ // Copied from com.android.server.wallpaper.WallpaperDataParser
+ private WallpaperDescription parseWallpaperDescription(TypedXmlPullParser parser,
+ ComponentName component) throws XmlPullParserException, IOException {
+
+ WallpaperDescription description = null;
+ int type = parser.next();
+ if (type == XmlPullParser.START_TAG && "description".equals(parser.getName())) {
+ // Always read the description if it's there - there may be one from a previous save
+ // with content handling enabled even if it's enabled now
+ description = WallpaperDescription.restoreFromXml(parser);
+ if (liveWallpaperContentHandling()) {
+ // null component means that wallpaper was last saved without content handling, so
+ // populate description from saved component
+ if (description.getComponent() == null) {
+ description = description.toBuilder().setComponent(component).build();
+ }
+ }
+ }
+ return description;
}
private int getAttributeInt(XmlPullParser parser, String name, int defValue) {
@@ -1037,14 +1079,16 @@ public class WallpaperBackupAgent extends BackupAgent {
// Intentionally blank
}
- private void applyComponentAtInstall(ComponentName componentName, int which) {
- PackageMonitor packageMonitor = getWallpaperPackageMonitor(
- componentName, which);
+ private void applyComponentAtInstall(ComponentName componentName,
+ @Nullable WallpaperDescription description, int which) {
+ PackageMonitor packageMonitor = getWallpaperPackageMonitor(componentName, description,
+ which);
packageMonitor.register(getBaseContext(), null, UserHandle.ALL, true);
}
@VisibleForTesting
- PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
+ PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+ @Nullable WallpaperDescription description, int which) {
return new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
@@ -1068,7 +1112,33 @@ public class WallpaperBackupAgent extends BackupAgent {
return;
}
- if (componentName.getPackageName().equals(packageName)) {
+ boolean useDescription = (liveWallpaperContentHandling() && description != null
+ && description.getComponent() != null);
+ if (useDescription && description.getComponent().getPackageName().equals(
+ packageName)) {
+ Slog.d(TAG, "Applying description " + description);
+ boolean success = mWallpaperManager.setWallpaperComponentWithDescription(
+ description, which);
+ WallpaperEventLogger logger = new WallpaperEventLogger(
+ mBackupManager.getDelayedRestoreLogger());
+ if (success) {
+ if ((which & FLAG_SYSTEM) != 0) {
+ logger.onSystemLiveWallpaperRestoredWithDescription(description);
+ }
+ if ((which & FLAG_LOCK) != 0) {
+ logger.onLockLiveWallpaperRestoredWithDescription(description);
+ }
+ } else {
+ if ((which & FLAG_SYSTEM) != 0) {
+ logger.onSystemLiveWallpaperRestoreFailed(
+ WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+ }
+ if ((which & FLAG_LOCK) != 0) {
+ logger.onLockLiveWallpaperRestoreFailed(
+ WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+ }
+ }
+ } else if (componentName.getPackageName().equals(packageName)) {
Slog.d(TAG, "Applying component " + componentName);
boolean success = mWallpaperManager.setWallpaperComponentWithFlags(
componentName, which);
@@ -1191,4 +1261,4 @@ public class WallpaperBackupAgent extends BackupAgent {
void setBackupManagerForTesting(BackupManager backupManager) {
mBackupManager = backupManager;
}
-} \ No newline at end of file
+}
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
index b25f95ab1936..69469e427266 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
@@ -16,12 +16,14 @@
package com.android.wallpaperbackup;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WallpaperInfo;
import android.app.backup.BackupManager;
import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+import android.app.wallpaper.WallpaperDescription;
import android.content.ComponentName;
import com.android.internal.annotations.VisibleForTesting;
@@ -53,6 +55,16 @@ public class WallpaperEventLogger {
@VisibleForTesting
static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock";
+ /* Live component used as system (or home) screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_DESCRIPTION_SYSTEM = "wlp_description_system";
+
+ /* Live component used as lock screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_DESCRIPTION_LOCK = "wlp_description_lock";
+
@BackupRestoreError
static final String ERROR_INELIGIBLE = "ineligible";
@BackupRestoreError
@@ -64,6 +76,8 @@ public class WallpaperEventLogger {
@BackupRestoreError
static final String ERROR_SET_COMPONENT_EXCEPTION = "exception_in_set_component";
@BackupRestoreError
+ static final String ERROR_SET_DESCRIPTION_EXCEPTION = "exception_in_set_description";
+ @BackupRestoreError
static final String ERROR_LIVE_PACKAGE_NOT_INSTALLED = "live_pkg_not_installed_in_restore";
private final BackupRestoreEventLogger mLogger;
@@ -115,11 +129,11 @@ public class WallpaperEventLogger {
}
void onSystemImageWallpaperRestored() {
- logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null);
+ logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, (ComponentName) null);
}
void onLockImageWallpaperRestored() {
- logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null);
+ logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, (ComponentName) null);
}
void onSystemLiveWallpaperRestored(ComponentName wpService) {
@@ -146,6 +160,13 @@ public class WallpaperEventLogger {
logRestoreFailureInternal(WALLPAPER_LIVE_LOCK, error);
}
+ void onSystemLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+ logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_SYSTEM, description);
+ }
+
+ void onLockLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+ logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_LOCK, description);
+ }
/**
@@ -168,15 +189,17 @@ public class WallpaperEventLogger {
*/
void onRestoreException(Exception exception) {
String error = exception.getClass().getName();
- if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains(
- WALLPAPER_LIVE_SYSTEM)) {
+ if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) || mProcessedDataTypes.contains(
+ WALLPAPER_LIVE_SYSTEM) || mProcessedDataTypes.contains(
+ WALLPAPER_DESCRIPTION_SYSTEM))) {
mLogger.logItemsRestoreFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error);
}
- if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains(
- WALLPAPER_LIVE_LOCK)) {
+ if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) || mProcessedDataTypes.contains(
+ WALLPAPER_LIVE_LOCK) || mProcessedDataTypes.contains(WALLPAPER_DESCRIPTION_LOCK))) {
mLogger.logItemsRestoreFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error);
}
}
+
private void logBackupSuccessInternal(@BackupRestoreDataType String which,
@Nullable WallpaperInfo liveComponentWallpaperInfo) {
mLogger.logItemsBackedUp(which, /* count */ 1);
@@ -197,6 +220,13 @@ public class WallpaperEventLogger {
mProcessedDataTypes.add(which);
}
+ private void logRestoreSuccessInternal(@BackupRestoreDataType String which,
+ @NonNull WallpaperDescription description) {
+ mLogger.logItemsRestored(which, /* count */ 1);
+ logRestoredLiveWallpaperDescription(which, description);
+ mProcessedDataTypes.add(which);
+ }
+
private void logRestoreFailureInternal(@BackupRestoreDataType String which,
@BackupRestoreError String error) {
mLogger.logItemsRestoreFailed(which, /* count */ 1, error);
@@ -216,4 +246,11 @@ public class WallpaperEventLogger {
mLogger.logRestoreMetadata(wallpaperType, wpService.getClassName());
}
}
+
+ private void logRestoredLiveWallpaperDescription(@BackupRestoreDataType String wallpaperType,
+ WallpaperDescription description) {
+ if (description != null) {
+ mLogger.logRestoreMetadata(wallpaperType, description.toString());
+ }
+ }
}
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index f5fb644502ab..c9f1b5857d10 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -16,6 +16,7 @@
package com.android.wallpaperbackup;
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
import static android.app.WallpaperManager.FLAG_LOCK;
import static android.app.WallpaperManager.FLAG_SYSTEM;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
@@ -27,6 +28,8 @@ import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE;
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA;
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER;
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -54,6 +57,7 @@ import android.app.backup.BackupManager;
import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -63,7 +67,10 @@ import android.graphics.Rect;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.wallpaper.WallpaperService;
+import android.util.Pair;
import android.util.SparseArray;
import android.util.Xml;
@@ -79,6 +86,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.RuleChain;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
@@ -113,12 +121,15 @@ public class WallpaperBackupAgentTest {
@Mock
private BackupManager mBackupManager;
- @Rule
- public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
private ContextWithServiceOverrides mContext;
private IsolatedWallpaperBackupAgent mWallpaperBackupAgent;
private ComponentName mWallpaperComponent;
+ private WallpaperDescription mWallpaperDescription;
+
+ private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
+ @Rule
+ public RuleChain mRuleChain = RuleChain.outerRule(new SetFlagsRule()).around(mTemporaryFolder);
@Before
public void setUp() {
@@ -135,6 +146,8 @@ public class WallpaperBackupAgentTest {
BackupAnnotations.OperationType.BACKUP);
mWallpaperComponent = new ComponentName(TEST_WALLPAPER_PACKAGE, "");
+ mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+ mWallpaperComponent).setId("id").build();
}
@After
@@ -366,11 +379,128 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_systemAndLock() throws IOException {
- mWallpaperBackupAgent.mIsDeviceInRestore = true;
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ public void testUpdateWallpaperComponent_immediate_systemAndLock() throws IOException {
+ mWallpaperBackupAgent.mPackageExists = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
+ assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ public void testUpdateWallpaperComponent_immediate_systemOnly()
+ throws IOException {
+ mWallpaperBackupAgent.mPackageExists = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
+ /* which */ FLAG_SYSTEM);
+
+ assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_immediate_systemAndLock()
+ throws IOException {
+ mWallpaperBackupAgent.mPackageExists = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(
+ new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+ FLAG_LOCK | FLAG_SYSTEM);
+
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithDescription(mWallpaperDescription,
+ FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_immediate_systemOnly() throws IOException {
+ mWallpaperBackupAgent.mPackageExists = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(
+ new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription,
+ FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_delayed_systemAndLock()
+ throws IOException {
+ mWallpaperBackupAgent.mIsDeviceInRestore = true;
+ mWallpaperBackupAgent.updateWallpaperComponent(
+ new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+ FLAG_LOCK | FLAG_SYSTEM);
+
+ // Imitate wallpaper component installation.
+ mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+ /* uid */0);
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithDescription(mWallpaperDescription,
+ FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_delayed_systemOnly() throws IOException {
+ mWallpaperBackupAgent.mIsDeviceInRestore = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(
+ new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+ // Imitate wallpaper component installation.
+ mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+ /* uid */0);
+
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithDescription(mWallpaperDescription,
+ FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ }
+
+ @Test
+ public void testUpdateWallpaperComponent_delayed_systemAndLock() throws IOException {
+ mWallpaperBackupAgent.mIsDeviceInRestore = true;
+
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
+ /* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
@@ -384,13 +514,12 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_systemOnly()
+ public void testUpdateWallpaperComponent_delayed_systemOnly()
throws IOException {
mWallpaperBackupAgent.mIsDeviceInRestore = true;
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_SYSTEM);
-
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
@@ -405,11 +534,11 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_deviceNotInRestore_doesNotApply()
+ public void testUpdateWallpaperComponent_delayed_deviceNotInRestore_doesNotApply()
throws IOException {
mWallpaperBackupAgent.mIsDeviceInRestore = false;
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
@@ -421,11 +550,11 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_differentPackageInstalled_doesNotApply()
+ public void testUpdateWallpaperComponent_delayed_differentPackageInstalled_doesNotApply()
throws IOException {
mWallpaperBackupAgent.mIsDeviceInRestore = false;
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate "wrong" wallpaper component installation.
@@ -745,9 +874,8 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_delayedRestore_logsSuccess() throws Exception {
+ public void testUpdateWallpaperComponent_delayed_succeeds_logsSuccess() throws Exception {
mWallpaperBackupAgent.mIsDeviceInRestore = true;
- when(mWallpaperManager.setWallpaperComponent(any())).thenReturn(true);
when(mWallpaperManager.setWallpaperComponentWithFlags(any(), eq(FLAG_LOCK | FLAG_SYSTEM)))
.thenReturn(true);
BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
@@ -755,7 +883,7 @@ public class WallpaperBackupAgentTest {
when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -771,15 +899,41 @@ public class WallpaperBackupAgentTest {
@Test
- public void testUpdateWallpaperComponent_delayedRestoreFails_logsFailure() throws Exception {
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_delayed_succeeds_logsSuccess() throws Exception {
+ mWallpaperBackupAgent.mIsDeviceInRestore = true;
+ when(mWallpaperManager.setWallpaperComponentWithDescription(any(),
+ eq(FLAG_LOCK | FLAG_SYSTEM))).thenReturn(true);
+ BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+ BackupAnnotations.OperationType.RESTORE);
+ when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+ mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+ /* which */ FLAG_LOCK | FLAG_SYSTEM);
+ // Imitate wallpaper component installation.
+ mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+ /* uid */0);
+
+ DataTypeResult system = getLoggingResult(WALLPAPER_DESCRIPTION_SYSTEM,
+ logger.getLoggingResults());
+ DataTypeResult lock = getLoggingResult(WALLPAPER_DESCRIPTION_LOCK,
+ logger.getLoggingResults());
+ assertThat(system).isNotNull();
+ assertThat(system.getSuccessCount()).isEqualTo(1);
+ assertThat(lock).isNotNull();
+ assertThat(lock.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void testUpdateWallpaperComponent_delayed_fails_logsFailure() throws Exception {
mWallpaperBackupAgent.mIsDeviceInRestore = true;
- when(mWallpaperManager.setWallpaperComponent(any())).thenReturn(false);
BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
BackupAnnotations.OperationType.RESTORE);
when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -793,7 +947,29 @@ public class WallpaperBackupAgentTest {
}
@Test
- public void testUpdateWallpaperComponent_delayedRestore_packageNotInstalled_logsFailure()
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void testUpdateWallpaperDescription_delayed_fails_logsFailure() throws Exception {
+ mWallpaperBackupAgent.mIsDeviceInRestore = true;
+ BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+ BackupAnnotations.OperationType.RESTORE);
+ when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+ mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+ /* which */ FLAG_LOCK | FLAG_SYSTEM);
+ // Imitate wallpaper component installation.
+ mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+ /* uid */0);
+
+ DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults());
+ assertThat(system).isNotNull();
+ assertThat(system.getFailCount()).isEqualTo(1);
+ assertThat(system.getErrors()).containsKey(
+ WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+ }
+
+ @Test
+ public void testUpdateWallpaperComponent_delayed_packageNotInstalled_logsFailure()
throws Exception {
mWallpaperBackupAgent.mIsDeviceInRestore = false;
BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
@@ -801,7 +977,7 @@ public class WallpaperBackupAgentTest {
when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
- mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+ mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
/* which */ FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
@@ -990,6 +1166,8 @@ public class WallpaperBackupAgentTest {
List<File> mBackedUpFiles = new ArrayList<>();
PackageMonitor mWallpaperPackageMonitor;
boolean mIsDeviceInRestore = false;
+ boolean mPackageExists = false;
+ int mGetPackageMonitorCallCount = 0;
@Override
protected void backupFile(File file, FullBackupDataOutput data) {
@@ -998,7 +1176,7 @@ public class WallpaperBackupAgentTest {
@Override
boolean servicePackageExists(ComponentName comp) {
- return false;
+ return mPackageExists;
}
@Override
@@ -1007,8 +1185,11 @@ public class WallpaperBackupAgentTest {
}
@Override
- PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
- mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, which);
+ PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+ WallpaperDescription description, int which) {
+ mGetPackageMonitorCallCount++;
+ mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, description,
+ which);
return mWallpaperPackageMonitor;
}
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
index 383bf2f68217..09aa23e713a5 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
@@ -16,6 +16,10 @@
package com.android.wallpaperbackup;
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -31,16 +35,20 @@ import android.app.WallpaperInfo;
import android.app.backup.BackupAnnotations;
import android.app.backup.BackupManager;
import android.app.backup.BackupRestoreEventLogger;
+import android.app.wallpaper.WallpaperDescription;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.service.wallpaper.WallpaperService;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -63,6 +71,10 @@ public class WallpaperEventLoggerTest {
private WallpaperEventLogger mWallpaperEventLogger;
private WallpaperInfo mWallpaperInfo;
+ private WallpaperDescription mWallpaperDescription;
+
+ @Rule
+ public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Before
public void setUp() throws Exception {
@@ -73,6 +85,8 @@ public class WallpaperEventLoggerTest {
mWallpaperInfo = getWallpaperInfo();
mWallpaperEventLogger = new WallpaperEventLogger(mMockBackupManager, mMockBackupAgent);
+ mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+ mWallpaperInfo.getComponent()).build();
}
@Test
@@ -263,6 +277,19 @@ public class WallpaperEventLoggerTest {
}
@Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void onSystemLiveWallpaperRestoredWithDescription_logsSuccess() {
+ setUpLoggerForRestore();
+
+ mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+ WALLPAPER_DESCRIPTION_SYSTEM);
+
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
public void onLockLiveWallpaperRestored_logsSuccess() {
setUpLoggerForRestore();
@@ -274,6 +301,17 @@ public class WallpaperEventLoggerTest {
}
@Test
+ public void onLockLiveWallpaperRestoredWithDescription_logsSuccess() {
+ setUpLoggerForRestore();
+
+ mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_DESCRIPTION_LOCK);
+
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
public void onImgWallpaperRestored_nullInfo_doesNotLogMetadata() {
setUpLoggerForRestore();
@@ -286,7 +324,7 @@ public class WallpaperEventLoggerTest {
@Test
- public void onLiveWallpaperRestored_logsMetadata() {
+ public void onSystemLiveWallpaperRestored_logsMetadata() {
setUpLoggerForRestore();
mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
@@ -296,6 +334,19 @@ public class WallpaperEventLoggerTest {
assertThat(result.getMetadataHash()).isNotNull();
}
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void onSystemLiveWallpaperRestoredDescription_logsMetadata() {
+ setUpLoggerForRestore();
+
+ mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+ WALLPAPER_DESCRIPTION_SYSTEM);
+
+ assertThat(result).isNotNull();
+ assertThat(result.getMetadataHash()).isNotNull();
+ }
+
@Test
public void onSystemImgWallpaperRestoreFailed_logsFail() {
@@ -373,7 +424,7 @@ public class WallpaperEventLoggerTest {
}
@Test
- public void onWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+ public void onSystemWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
setUpLoggerForRestore();
mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
@@ -383,6 +434,41 @@ public class WallpaperEventLoggerTest {
assertThat(result).isNull();
}
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void onSystemWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+ setUpLoggerForRestore();
+ mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+ mWallpaperEventLogger.onRestoreException(new Exception());
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_SYSTEM);
+
+ assertThat(result).isNull();
+ }
+
+ @Test
+ public void onLockWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+ setUpLoggerForRestore();
+ mWallpaperEventLogger.onLockLiveWallpaperRestored(mWallpaperInfo.getComponent());
+
+ mWallpaperEventLogger.onRestoreException(new Exception());
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+ assertThat(result).isNull();
+ }
+
+ @Test
+ @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+ public void onLockWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+ setUpLoggerForRestore();
+ mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+ mWallpaperEventLogger.onRestoreException(new Exception());
+ BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+ assertThat(result).isNull();
+ }
+
private BackupRestoreEventLogger.DataTypeResult getLogsForType(String dataType) {
for (BackupRestoreEventLogger.DataTypeResult result : mEventLogger.getLoggingResults()) {
if ((result.getDataType()).equals(dataType)) {
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
index b83216af95fe..c2bf8d82e272 100755
--- a/ravenwood/scripts/ravenwood-stats-collector.sh
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -29,21 +29,46 @@ mkdir -p $out_dir
mkdir -p $keep_all_dir
mkdir -p $dump_dir
-# Where the input files are.
-path=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/ravenwood-stats-checker/x86_64/
-timestamp="$(date --iso-8601=seconds)"
+stats_checker_module="ravenwood-stats-checker"
+minfo=$OUT/module-info.json
-m() {
- ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode "$@"
-}
+timestamp="$(date --iso-8601=seconds)"
-# Building this will generate the files we need.
-m ravenwood-stats-checker
+# First, use jq to get the output files from the checker module. This will be something like this:
+#
+# ---
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/framework-configinfrastructure_apis.csv
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/framework-configinfrastructure_dump.txt
+# :
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/hoststubgen_services.core_stats.csv
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/ravenwood-stats-checker
+# ---
+# Then, use grep to find the script's path (the last line in the above examle)
+script_path="$(
+ jq -r ".\"$stats_checker_module\".installed | .[]" $minfo |
+ grep '/ravenwood-stats-checker$'
+)"
+
+if [[ "$script_path" == "" ]] ; then
+ echo "Error: $stats_checker_module script not found from $minfo"
+ exit 1
+fi
+
+# This is the directory where our input files are.
+script_dir="$ANDROID_BUILD_TOP/$(dirname "$script_path")"
+
+# Clear it before (re-)buildign the script, to make sure we won't have stale files.
+rm -fr "$script_dir"
+
+# Then build it, which will also collect the input files in the same dir.
+echo "Collecting the input files..."
+m "$stats_checker_module"
# Start...
-cd $path
+echo "Files directory is: $script_dir"
+cd "$script_dir"
dump() {
local jar=$1
@@ -55,6 +80,7 @@ dump() {
collect_stats() {
local out="$1"
+ local desc="$2"
{
# Copy the header, with the first column appended.
echo -n "Jar,Generated Date,"
@@ -66,11 +92,12 @@ collect_stats() {
dump "framework-statsd" framework-statsd_stats.csv
} > "$out"
- echo "Stats CVS created at $out"
+ echo "Stats CVS created at $out$desc"
}
collect_apis() {
local out="$1"
+ local desc="$2"
{
# Copy the header, with the first column appended.
echo -n "Jar,Generated Date,"
@@ -82,12 +109,12 @@ collect_apis() {
dump "framework-statsd" framework-statsd_apis.csv
} > "$out"
- echo "API CVS created at $out"
+ echo "API CVS created at $out$desc"
}
-collect_stats $stats
-collect_apis $apis
+collect_stats $stats " (import it as 'ravenwood_stats')"
+collect_apis $apis " (import it as 'ravenwood_supported_apis')"
cp *keep_all.txt $keep_all_dir
echo "Keep all files created at:"
diff --git a/ravenwood/tools/hoststubgen/Android.bp b/ravenwood/tools/hoststubgen/Android.bp
index 004834eed983..e605318f4a10 100644
--- a/ravenwood/tools/hoststubgen/Android.bp
+++ b/ravenwood/tools/hoststubgen/Android.bp
@@ -99,6 +99,7 @@ java_library_host {
"ow2-asm-commons",
"ow2-asm-tree",
"ow2-asm-util",
+ "apache-commons-compress",
],
}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
index 9045db210495..ea8c25b6833c 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
@@ -15,13 +15,24 @@
*/
package com.android.hoststubgen
+import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.getOuterClassNameFromFullClassName
import com.android.hoststubgen.asm.getPackageNameFromFullClassName
import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.StatsLabel
import org.objectweb.asm.Opcodes
import java.io.PrintWriter
-open class HostStubGenStats {
+/**
+ * TODO This is for the legacy API coverage stats CSV that shows how many APIs are "supported"
+ * in each class with some heuristics. We created [ApiDumper] later, which dumpps all methods
+ * with the "supported" status. We should update the coverage dashboard to use the [ApiDumper]
+ * output and remove this class, once we port all the heuristics to [ApiDumper] as well.
+ * (For example, this class ignores non-public and/or abstract methods, but [ApiDumper] shows
+ * all of them in the same way. We should probably mark them as "Boring" or maybe "Ignore"
+ * for [ApiDumper])
+ */
+open class HostStubGenStats(val classes: ClassNodes) {
data class Stats(
var supported: Int = 0,
var total: Int = 0,
@@ -30,14 +41,6 @@ open class HostStubGenStats {
private val stats = mutableMapOf<String, Stats>()
- data class Api(
- val fullClassName: String,
- val methodName: String,
- val methodDesc: String,
- )
-
- private val apis = mutableListOf<Api>()
-
fun onVisitPolicyForMethod(
fullClassName: String,
methodName: String,
@@ -45,16 +48,16 @@ open class HostStubGenStats {
policy: FilterPolicyWithReason,
access: Int
) {
- if (policy.policy.isSupported) {
- apis.add(Api(fullClassName, methodName, descriptor))
- }
-
// Ignore methods that aren't public
if ((access and Opcodes.ACC_PUBLIC) == 0) return
// Ignore methods that are abstract
if ((access and Opcodes.ACC_ABSTRACT) != 0) return
+
// Ignore methods where policy isn't relevant
- if (policy.isIgnoredForStats) return
+ val statsLabel = policy.statsLabel
+ if (statsLabel == StatsLabel.Ignored) return
+
+ val cn = classes.findClass(fullClassName) ?: return
val packageName = getPackageNameFromFullClassName(fullClassName)
val className = getOuterClassNameFromFullClassName(fullClassName)
@@ -70,7 +73,7 @@ open class HostStubGenStats {
val packageStats = stats.getOrPut(packageName) { Stats() }
val classStats = packageStats.children.getOrPut(className) { Stats() }
- if (policy.policy.isSupported) {
+ if (statsLabel == StatsLabel.Supported) {
packageStats.supported += 1
classStats.supported += 1
}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
index b2af7827f8c5..a62f66dd18e5 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
@@ -16,6 +16,15 @@
package com.android.hoststubgen
import java.io.PrintWriter
+import java.util.zip.CRC32
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
+
+/**
+ * Whether to skip compression when adding processed entries back to a zip file.
+ */
+private const val SKIP_COMPRESSION = false
/**
* Name of this executable. Set it in the main method.
@@ -118,3 +127,29 @@ inline fun runMainWithBoilerplate(realMain: () -> Unit) {
System.exit(if (success) 0 else 1 )
}
+
+/**
+ * Copy a single ZIP entry to the output.
+ */
+fun copyZipEntry(
+ inZip: ZipFile,
+ entry: ZipArchiveEntry,
+ out: ZipArchiveOutputStream,
+) {
+ inZip.getRawInputStream(entry).use { out.addRawArchiveEntry(entry, it) }
+}
+
+/**
+ * Add a single ZIP entry with data.
+ */
+fun ZipArchiveOutputStream.addBytesEntry(name: String, data: ByteArray) {
+ val newEntry = ZipArchiveEntry(name)
+ if (SKIP_COMPRESSION) {
+ newEntry.method = 0
+ newEntry.size = data.size.toLong()
+ newEntry.crc = CRC32().apply { update(data) }.value
+ }
+ putArchiveEntry(newEntry)
+ write(data)
+ closeArchiveEntry()
+}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
index e2647eb13ed3..40d343ab9658 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
@@ -18,21 +18,20 @@ package com.android.hoststubgen.asm
import com.android.hoststubgen.ClassParseException
import com.android.hoststubgen.InvalidJarFileException
import com.android.hoststubgen.log
-import org.objectweb.asm.ClassReader
-import org.objectweb.asm.tree.AnnotationNode
-import org.objectweb.asm.tree.ClassNode
-import org.objectweb.asm.tree.FieldNode
-import org.objectweb.asm.tree.MethodNode
-import org.objectweb.asm.tree.TypeAnnotationNode
-import java.io.BufferedInputStream
import java.io.PrintWriter
import java.util.Arrays
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Consumer
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipFile
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.tree.AnnotationNode
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.FieldNode
+import org.objectweb.asm.tree.MethodNode
+import org.objectweb.asm.tree.TypeAnnotationNode
/**
* Stores all classes loaded from a jar file, in a form of [ClassNode]
@@ -189,7 +188,8 @@ class ClassNodes {
* Load all the classes, without code.
*/
fun loadClassStructures(
- inJar: String,
+ inJar: ZipFile,
+ jarName: String,
timeCollector: Consumer<Double>? = null,
): ClassNodes {
val allClasses = ClassNodes()
@@ -201,20 +201,19 @@ class ClassNodes {
val exception = AtomicReference<Throwable>()
// Called on a BG thread. Read a single jar entry and add it to [allClasses].
- fun parseClass(inZip: ZipFile, entry: ZipEntry) {
+ fun parseClass(inZip: ZipFile, entry: ZipArchiveEntry) {
try {
- inZip.getInputStream(entry).use { ins ->
- val cr = ClassReader(BufferedInputStream(ins))
- val cn = ClassNode()
- cr.accept(
- cn, ClassReader.SKIP_CODE
- or ClassReader.SKIP_DEBUG
- or ClassReader.SKIP_FRAMES
- )
- synchronized(allClasses) {
- if (!allClasses.addClass(cn)) {
- log.w("Duplicate class found: ${cn.name}")
- }
+ val classBytes = inZip.getInputStream(entry).use { it.readAllBytes() }
+ val cr = ClassReader(classBytes)
+ val cn = ClassNode()
+ cr.accept(
+ cn, ClassReader.SKIP_CODE
+ or ClassReader.SKIP_DEBUG
+ or ClassReader.SKIP_FRAMES
+ )
+ synchronized(allClasses) {
+ if (!allClasses.addClass(cn)) {
+ log.w("Duplicate class found: ${cn.name}")
}
}
} catch (e: Throwable) {
@@ -224,35 +223,30 @@ class ClassNodes {
}
// Actually open the jar and read it on worker threads.
- val time = log.iTime("Reading class structure from $inJar") {
+ val time = log.iTime("Reading class structure from $jarName") {
log.withIndent {
- ZipFile(inJar).use { inZip ->
- val inEntries = inZip.entries()
-
- while (inEntries.hasMoreElements()) {
- val entry = inEntries.nextElement()
-
- if (entry.name.endsWith(".class")) {
- executor.submit {
- parseClass(inZip, entry)
- }
- } else if (entry.name.endsWith(".dex")) {
- // Seems like it's an ART jar file. We can't process it.
- // It's a fatal error.
- throw InvalidJarFileException(
- "$inJar is not a desktop jar file."
- + " It contains a *.dex file."
- )
- } else {
- // Unknown file type. Skip.
+ inJar.entries.asSequence().forEach { entry ->
+ if (entry.name.endsWith(".class")) {
+ executor.submit {
+ parseClass(inJar, entry)
}
+ } else if (entry.name.endsWith(".dex")) {
+ // Seems like it's an ART jar file. We can't process it.
+ // It's a fatal error.
+ throw InvalidJarFileException(
+ "$jarName is not a desktop jar file."
+ + " It contains a *.dex file."
+ )
+ } else {
+ // Unknown file type. Skip.
}
- // Wait for all the work to complete. (must do it before closing the zip)
- log.i("Waiting for all loaders to finish...")
- executor.shutdown()
- executor.awaitTermination(5, TimeUnit.MINUTES)
- log.i("All loaders to finished.")
}
+
+ // Wait for all the work to complete. (must do it before closing the zip)
+ log.i("Waiting for all loaders to finish...")
+ executor.shutdown()
+ executor.awaitTermination(5, TimeUnit.MINUTES)
+ log.i("All loaders to finished.")
}
// If any exception is detected, throw it.
@@ -261,13 +255,13 @@ class ClassNodes {
}
if (allClasses.size == 0) {
- log.w("$inJar contains no *.class files.")
+ log.w("$jarName contains no *.class files.")
} else {
- log.i("Loaded ${allClasses.size} classes from $inJar.")
+ log.i("Loaded ${allClasses.size} classes from $jarName.")
}
}
timeCollector?.accept(time)
return allClasses
}
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
index 5e4e70f0cbaa..bb8cdccafaa6 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
@@ -25,6 +25,7 @@ import com.android.hoststubgen.csvEscape
import com.android.hoststubgen.filters.FilterPolicy
import com.android.hoststubgen.filters.FilterPolicyWithReason
import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.filters.StatsLabel
import com.android.hoststubgen.log
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
@@ -44,7 +45,10 @@ class ApiDumper(
val descriptor: String,
)
- private val javaStandardApiPolicy = FilterPolicy.Keep.withReason("Java standard API")
+ private val javaStandardApiPolicy = FilterPolicy.Keep.withReason(
+ "Java standard API",
+ StatsLabel.Supported,
+ )
private val shownMethods = mutableSetOf<MethodKey>()
@@ -53,7 +57,7 @@ class ApiDumper(
*/
fun dump() {
pw.printf("PackageName,ClassName,FromSubclass,DeclareClass,MethodName,MethodDesc" +
- ",Supported,Policy,Reason\n")
+ ",Supported,Policy,Reason,SupportedLabel\n")
classes.forEach { classNode ->
shownMethods.clear()
@@ -68,23 +72,36 @@ class ApiDumper(
methodClassName: String,
methodName: String,
methodDesc: String,
- policy: FilterPolicyWithReason,
+ classPolicy: FilterPolicyWithReason,
+ methodPolicy: FilterPolicyWithReason,
) {
+ if (methodPolicy.statsLabel == StatsLabel.Ignored) {
+ return
+ }
+ // Label hack -- if the method is supported, but the class is boring, then the
+ // method is boring too.
+ var methodLabel = methodPolicy.statsLabel
+ if (methodLabel == StatsLabel.SupportedButBoring
+ && classPolicy.statsLabel == StatsLabel.SupportedButBoring) {
+ methodLabel = classPolicy.statsLabel
+ }
+
pw.printf(
- "%s,%s,%d,%s,%s,%s,%d,%s,%s\n",
+ "%s,%s,%d,%s,%s,%s,%d,%s,%s,%s\n",
csvEscape(classPackage),
csvEscape(className),
if (isSuperClass) { 1 } else { 0 },
csvEscape(methodClassName),
csvEscape(methodName),
csvEscape(methodDesc),
- if (policy.policy.isSupported) { 1 } else { 0 },
- policy.policy,
- csvEscape(policy.reason),
+ methodLabel.statValue,
+ methodPolicy.policy,
+ csvEscape(methodPolicy.reason),
+ methodLabel,
)
}
- private fun isDuplicate(methodName: String, methodDesc: String): Boolean {
+ private fun shownAlready(methodName: String, methodDesc: String): Boolean {
val methodKey = MethodKey(methodName, methodDesc)
if (shownMethods.contains(methodKey)) {
@@ -98,6 +115,12 @@ class ApiDumper(
dumpClass: ClassNode,
methodClass: ClassNode,
) {
+ val classPolicy = filter.getPolicyForClass(dumpClass.name)
+ if (classPolicy.statsLabel == StatsLabel.Ignored) {
+ return
+ }
+ log.d("Class ${dumpClass.name} -- policy $classPolicy")
+
val pkg = getPackageNameFromFullClassName(dumpClass.name).toHumanReadableClassName()
val cls = getClassNameFromFullClassName(dumpClass.name).toHumanReadableClassName()
@@ -112,23 +135,23 @@ class ApiDumper(
}
}
// If we already printed the method from a subclass, don't print it.
- if (isDuplicate(method.name, method.desc)) {
+ if (shownAlready(method.name, method.desc)) {
return@forEach
}
- val policy = filter.getPolicyForMethod(methodClass.name, method.name, method.desc)
+ val methodPolicy = filter.getPolicyForMethod(methodClass.name, method.name, method.desc)
// Let's skip "Remove" APIs. Ideally we want to print it, just to make the CSV
// complete, we still need to hide methods substituted (== @RavenwoodReplace) methods
// and for now we don't have an easy way to detect it.
- if (policy.policy == FilterPolicy.Remove) {
+ if (methodPolicy.policy == FilterPolicy.Remove) {
return@forEach
}
val renameTo = filter.getRenameTo(methodClass.name, method.name, method.desc)
dumpMethod(pkg, cls, isSuperClass, methodClass.name.toHumanReadableClassName(),
- renameTo ?: method.name, method.desc, policy)
+ renameTo ?: method.name, method.desc, classPolicy, methodPolicy)
}
// Dump super class methods.
@@ -155,10 +178,13 @@ class ApiDumper(
dump(dumpClass, methodClass)
return
}
- if (methodClassName.startsWith("java/") ||
- methodClassName.startsWith("javax/")
- ) {
- dumpStandardClass(dumpClass, methodClassName)
+
+ // Dump overriding methods from Java standard classes, except for the Object methods,
+ // which are obvious.
+ if (methodClassName.startsWith("java/") || methodClassName.startsWith("javax/")) {
+ if (methodClassName != "java/lang/Object") {
+ dumpStandardClass(dumpClass, methodClassName)
+ }
return
}
log.w("Super class or interface $methodClassName (used by ${dumpClass.name}) not found.")
@@ -188,12 +214,12 @@ class ApiDumper(
val methodDesc = Type.getMethodDescriptor(method)
// If we already printed the method from a subclass, don't print it.
- if (isDuplicate(methodName, methodDesc)) {
+ if (shownAlready(methodName, methodDesc)) {
return@forEach
}
dumpMethod(pkg, cls, true, methodClassName,
- methodName, methodDesc, javaStandardApiPolicy)
+ methodName, methodDesc, javaStandardApiPolicy, javaStandardApiPolicy)
}
} catch (e: ClassNotFoundException) {
log.w("JVM type $methodClassName (used by ${dumpClass.name}) not found.")
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
index 81c26ffdf1f4..c3c870f59347 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
@@ -155,7 +155,10 @@ enum class FilterPolicy(val policyStringOrPrefix: String) {
/**
* Create a [FilterPolicyWithReason] with a given reason.
*/
- fun withReason(reason: String): FilterPolicyWithReason {
- return FilterPolicyWithReason(this, reason)
+ fun withReason(
+ reason: String,
+ statsLabelOverride: StatsLabel? = null,
+ ): FilterPolicyWithReason {
+ return FilterPolicyWithReason(this, reason, statsLabelOverride = statsLabelOverride)
}
}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
index b10165b835f2..7358a0bfb3e6 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
@@ -16,32 +16,54 @@
package com.android.hoststubgen.filters
/**
+ * How each entry should be handled on the dashboard.
+ */
+enum class StatsLabel(val statValue: Int, val label: String) {
+ /** Entry shouldn't show up in the dashboard. */
+ Ignored(-1, ""),
+
+ /** Entry should be shown as "not supported" */
+ NotSupported(0, "NotSupported"),
+
+ /**
+ * Entry should be shown as "supported", but are too "boring" to show on the dashboard,
+ * e.g. annotation classes.
+ */
+ SupportedButBoring(1, "Boring"),
+
+ /** Entry should be shown as "supported" */
+ Supported(2, "Supported"),
+}
+
+/**
* Captures a [FilterPolicy] with a human-readable reason.
*/
data class FilterPolicyWithReason (
- val policy: FilterPolicy,
- val reason: String = "",
+ val policy: FilterPolicy,
+ val reason: String = "",
+ private val statsLabelOverride: StatsLabel? = null
) {
/**
* Return a new [FilterPolicy] with an updated reason, while keeping the original reason
* as an "inner-reason".
*/
- fun wrapReason(reason: String): FilterPolicyWithReason {
- return FilterPolicyWithReason(policy, "$reason [inner-reason: ${this.reason}]")
+ fun wrapReason(reason: String, statsLabelOverride: StatsLabel? = null): FilterPolicyWithReason {
+ return FilterPolicyWithReason(
+ policy,
+ "$reason [inner-reason: ${this.reason}]",
+ statsLabelOverride = statsLabelOverride,
+ )
}
override fun toString(): String {
- return "[$policy - reason: $reason]"
+ return "[$policy/$statsLabel - reason: $reason]"
}
- /** Returns whether this policy should be ignored for stats. */
- val isIgnoredForStats: Boolean
- get() {
- return reason.contains("anonymous-inner-class")
- || reason.contains("is-annotation")
- || reason.contains("is-enum")
- || reason.contains("is-synthetic-method")
- || reason.contains("special-class")
- || reason.contains("substitute-to")
+ val statsLabel: StatsLabel get() {
+ statsLabelOverride?.let { return it }
+ if (policy.isSupported) {
+ return StatsLabel.Supported
}
+ return StatsLabel.NotSupported
+ }
}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
index d44d016f7c5b..1145da635606 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
@@ -48,7 +48,11 @@ class ImplicitOutputFilter(
// If the outer class needs to be in impl, it should be in impl too.
val outerPolicy = outermostFilter.getPolicyForClass(cn.outerClass)
if (outerPolicy.policy.needsInOutput) {
- return FilterPolicy.KeepClass.withReason("anonymous-inner-class")
+ // We keep this class, but don't need to show it in the dashboard.
+ return FilterPolicy.KeepClass.withReason(
+ "anonymous-inner-class",
+ StatsLabel.Ignored,
+ )
}
}
return null
@@ -62,6 +66,15 @@ class ImplicitOutputFilter(
// Use the implicit policy, if any.
getClassImplicitPolicy(cn)?.let { return it }
+ // If it's an annotation class and we need to keep it, then
+ // change the reason to hide it from the stats.
+ if (cn.isAnnotation() && fallback.policy.needsInOutput) {
+ return FilterPolicy.KeepClass.withReason(
+ "is-annotation",
+ StatsLabel.Ignored,
+ )
+ }
+
return fallback
}
@@ -102,14 +115,20 @@ class ImplicitOutputFilter(
if (cn.isEnum()) {
mn?.let { mn ->
if (isAutoGeneratedEnumMember(mn)) {
- return memberPolicy.withReason(classPolicy.reason).wrapReason("is-enum")
+ return memberPolicy.withReason(classPolicy.reason).wrapReason(
+ "is-enum",
+ StatsLabel.Ignored,
+ )
}
}
}
// Keep (or stub) all members of annotations.
if (cn.isAnnotation()) {
- return memberPolicy.withReason(classPolicy.reason).wrapReason("is-annotation")
+ return memberPolicy.withReason(classPolicy.reason).wrapReason(
+ "is-annotation",
+ StatsLabel.Ignored,
+ )
}
mn?.let {
@@ -117,7 +136,8 @@ class ImplicitOutputFilter(
// For synthetic methods (such as lambdas), let's just inherit the class's
// policy.
return memberPolicy.withReason(classPolicy.reason).wrapReason(
- "is-synthetic-method"
+ "is-synthetic-method",
+ StatsLabel.Ignored,
)
}
}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
index 00e7d77fa6e7..57309b49a2cd 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
@@ -22,6 +22,9 @@ import com.android.hoststubgen.asm.isNative
* For native methods that weren't handled by outer filters, we keep it so that
* native method registration will not crash at runtime. Ideally we shouldn't need
* this, but in practice unsupported native method registrations do occur.
+ *
+ * Native methods kept by this filter will all have a "Keep" policy, but they won't show
+ * up as "supported" in the stats dashboard beucase we set reallySupported to false.
*/
class KeepNativeFilter(
private val classes: ClassNodes,
@@ -34,7 +37,7 @@ class KeepNativeFilter(
): FilterPolicyWithReason {
return classes.findMethod(className, methodName, descriptor)?.let { mn ->
if (mn.isNative()) {
- FilterPolicy.Keep.withReason("native-preserve")
+ FilterPolicy.Keep.withReason("native-preserve", StatsLabel.NotSupported)
} else {
null
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 333540573364..3291ff6b8bc6 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -19,13 +19,11 @@ import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.dumper.ApiDumper
import com.android.hoststubgen.filters.FilterPolicy
import com.android.hoststubgen.filters.printAsTextPolicy
-import java.io.BufferedInputStream
-import java.io.BufferedOutputStream
import java.io.FileOutputStream
import java.io.PrintWriter
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
-import java.util.zip.ZipOutputStream
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
/**
* Actual main class.
@@ -33,10 +31,12 @@ import java.util.zip.ZipOutputStream
class HostStubGen(val options: HostStubGenOptions) {
fun run() {
val errors = HostStubGenErrors()
- val stats = HostStubGenStats()
+ val inJar = ZipFile(options.inJar.get)
// Load all classes.
- val allClasses = ClassNodes.loadClassStructures(options.inJar.get)
+ val allClasses = ClassNodes.loadClassStructures(inJar, options.inJar.get)
+
+ val stats = HostStubGenStats(allClasses)
// Dump the classes, if specified.
options.inputJarDumpFile.ifSet {
@@ -59,7 +59,7 @@ class HostStubGen(val options: HostStubGenOptions) {
val processor = HostStubGenClassProcessor(options, allClasses, errors, stats)
// Transform the jar.
- convert(
+ inJar.convert(
options.inJar.get,
options.outJar.get,
processor,
@@ -88,7 +88,7 @@ class HostStubGen(val options: HostStubGenOptions) {
/**
* Convert a JAR file into "stub" and "impl" JAR files.
*/
- private fun convert(
+ private fun ZipFile.convert(
inJar: String,
outJar: String?,
processor: HostStubGenClassProcessor,
@@ -100,45 +100,39 @@ class HostStubGen(val options: HostStubGenOptions) {
log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")
log.iTime("Transforming jar") {
- var itemIndex = 0
var numItemsProcessed = 0
var numItems = -1 // == Unknown
log.withIndent {
- // Open the input jar file and process each entry.
- ZipFile(inJar).use { inZip ->
-
- numItems = inZip.size()
- val shardStart = numItems * shard / numShards
- val shardNextStart = numItems * (shard + 1) / numShards
-
- maybeWithZipOutputStream(outJar) { outStream ->
- val inEntries = inZip.entries()
- while (inEntries.hasMoreElements()) {
- val entry = inEntries.nextElement()
- val inShard = (shardStart <= itemIndex)
- && (itemIndex < shardNextStart)
- itemIndex++
- if (!inShard) {
- continue
- }
- convertSingleEntry(inZip, entry, outStream, processor)
- numItemsProcessed++
+ val entries = entries.toList()
+
+ numItems = entries.size
+ val shardStart = numItems * shard / numShards
+ val shardNextStart = numItems * (shard + 1) / numShards
+
+ maybeWithZipOutputStream(outJar) { outStream ->
+ entries.forEachIndexed { itemIndex, entry ->
+ val inShard = (shardStart <= itemIndex)
+ && (itemIndex < shardNextStart)
+ if (!inShard) {
+ return@forEachIndexed
}
- log.i("Converted all entries.")
+ convertSingleEntry(this, entry, outStream, processor)
+ numItemsProcessed++
}
- outJar?.let { log.i("Created: $it") }
+ log.i("Converted all entries.")
}
+ outJar?.let { log.i("Created: $it") }
}
log.i("%d / %d item(s) processed.", numItemsProcessed, numItems)
}
}
- private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
+ private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipArchiveOutputStream?) -> T): T {
if (filename == null) {
return block(null)
}
- return ZipOutputStream(BufferedOutputStream(FileOutputStream(filename))).use(block)
+ return ZipArchiveOutputStream(FileOutputStream(filename).buffered()).use(block)
}
/**
@@ -146,8 +140,8 @@ class HostStubGen(val options: HostStubGenOptions) {
*/
private fun convertSingleEntry(
inZip: ZipFile,
- entry: ZipEntry,
- outStream: ZipOutputStream?,
+ entry: ZipArchiveEntry,
+ outStream: ZipArchiveOutputStream?,
processor: HostStubGenClassProcessor
) {
log.d("Entry: %s", entry.name)
@@ -181,32 +175,12 @@ class HostStubGen(val options: HostStubGenOptions) {
}
/**
- * Copy a single ZIP entry to the output.
- */
- private fun copyZipEntry(
- inZip: ZipFile,
- entry: ZipEntry,
- out: ZipOutputStream,
- ) {
- // TODO: It seems like copying entries this way is _very_ slow,
- // even with out.setLevel(0). Look for other ways to do it.
-
- inZip.getInputStream(entry).use { ins ->
- // Copy unknown entries as is to the impl out. (but not to the stub out.)
- val outEntry = ZipEntry(entry.name)
- out.putNextEntry(outEntry)
- ins.transferTo(out)
- out.closeEntry()
- }
- }
-
- /**
* Convert a single class.
*/
private fun processSingleClass(
inZip: ZipFile,
- entry: ZipEntry,
- outStream: ZipOutputStream?,
+ entry: ZipArchiveEntry,
+ outStream: ZipArchiveOutputStream?,
processor: HostStubGenClassProcessor
) {
val classInternalName = entry.name.replaceFirst("\\.class$".toRegex(), "")
@@ -227,12 +201,10 @@ class HostStubGen(val options: HostStubGenOptions) {
if (outStream != null) {
log.v("Creating class: %s Policy: %s", classInternalName, classPolicy)
log.withIndent {
- BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
- val newEntry = ZipEntry(newName)
- outStream.putNextEntry(newEntry)
- val classBytecode = bis.readAllBytes()
- outStream.write(processor.processClassBytecode(classBytecode))
- outStream.closeEntry()
+ inZip.getInputStream(entry).use { zis ->
+ var classBytecode = zis.readAllBytes()
+ classBytecode = processor.processClassBytecode(classBytecode)
+ outStream.addBytesEntry(newName, classBytecode)
}
}
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
index 761748265726..0c2269ab5e0d 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -33,7 +33,7 @@ def run_diff(file1, file2):
'--ignore-space-change',
# Ignore the class file version.
- '--ignore-matching-lines=^ *\(major\|minor\) version:$',
+ '--ignore-matching-lines=^ *\\(major\\|minor\\) version:$',
# We shouldn't need `--ignore-matching-lines`, but somehow
# the golden files were generated without these lines for b/388562869,
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
index 04e3bda2ba27..8e36323fd495 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
@@ -17,17 +17,17 @@ package com.android.platform.test.ravenwood.ravenizer
import com.android.hoststubgen.GeneralUserErrorException
import com.android.hoststubgen.HostStubGenClassProcessor
+import com.android.hoststubgen.addBytesEntry
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.zipEntryNameToClassName
+import com.android.hoststubgen.copyZipEntry
import com.android.hoststubgen.executableName
import com.android.hoststubgen.log
import com.android.platform.test.ravenwood.ravenizer.adapter.RunnerRewritingAdapter
-import java.io.BufferedInputStream
-import java.io.BufferedOutputStream
import java.io.FileOutputStream
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
-import java.util.zip.ZipOutputStream
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.ClassWriter
@@ -93,13 +93,14 @@ class Ravenizer {
val stats = RavenizerStats()
stats.totalTime = log.nTime {
- val allClasses = ClassNodes.loadClassStructures(options.inJar.get) {
+ val inJar = ZipFile(options.inJar.get)
+ val allClasses = ClassNodes.loadClassStructures(inJar, options.inJar.get) {
stats.loadStructureTime = it
}
val processor = HostStubGenClassProcessor(options, allClasses)
- process(
- options.inJar.get,
+ inJar.process(
+ options.outJar.get,
options.outJar.get,
options.enableValidation.get,
options.fatalValidation.get,
@@ -111,7 +112,7 @@ class Ravenizer {
log.i(stats.toString())
}
- private fun process(
+ private fun ZipFile.process(
inJar: String,
outJar: String,
enableValidation: Boolean,
@@ -138,40 +139,34 @@ class Ravenizer {
}
stats.totalProcessTime = log.vTime("$executableName processing $inJar") {
- ZipFile(inJar).use { inZip ->
- val inEntries = inZip.entries()
-
- stats.totalEntries = inZip.size()
-
- ZipOutputStream(BufferedOutputStream(FileOutputStream(outJar))).use { outZip ->
- while (inEntries.hasMoreElements()) {
- val entry = inEntries.nextElement()
-
- if (entry.name.endsWith(".dex")) {
- // Seems like it's an ART jar file. We can't process it.
- // It's a fatal error.
- throw GeneralUserErrorException(
- "$inJar is not a desktop jar file. It contains a *.dex file."
- )
- }
+ ZipArchiveOutputStream(FileOutputStream(outJar).buffered()).use { outZip ->
+ entries.asSequence().forEach { entry ->
+ stats.totalEntries++
+ if (entry.name.endsWith(".dex")) {
+ // Seems like it's an ART jar file. We can't process it.
+ // It's a fatal error.
+ throw GeneralUserErrorException(
+ "$inJar is not a desktop jar file. It contains a *.dex file."
+ )
+ }
- if (stripMockito && entry.name.isMockitoFile()) {
- // Skip this entry
- continue
- }
+ if (stripMockito && entry.name.isMockitoFile()) {
+ // Skip this entry
+ return@forEach
+ }
- val className = zipEntryNameToClassName(entry.name)
+ val className = zipEntryNameToClassName(entry.name)
- if (className != null) {
- stats.totalClasses += 1
- }
+ if (className != null) {
+ stats.totalClasses += 1
+ }
- if (className != null &&
- shouldProcessClass(processor.allClasses, className)) {
- processSingleClass(inZip, entry, outZip, processor, stats)
- } else {
- // Too slow, let's use merge_zips to bring back the original classes.
- copyZipEntry(inZip, entry, outZip, stats)
+ if (className != null &&
+ shouldProcessClass(processor.allClasses, className)) {
+ processSingleClass(this, entry, outZip, processor, stats)
+ } else {
+ stats.totalCopyTime += log.nTime {
+ copyZipEntry(this, entry, outZip)
}
}
}
@@ -179,53 +174,25 @@ class Ravenizer {
}
}
- /**
- * Copy a single ZIP entry to the output.
- */
- private fun copyZipEntry(
- inZip: ZipFile,
- entry: ZipEntry,
- out: ZipOutputStream,
- stats: RavenizerStats,
- ) {
- stats.totalCopyTime += log.nTime {
- inZip.getInputStream(entry).use { ins ->
- // Copy unknown entries as is to the impl out. (but not to the stub out.)
- val outEntry = ZipEntry(entry.name)
- outEntry.method = 0
- outEntry.size = entry.size
- outEntry.crc = entry.crc
- out.putNextEntry(outEntry)
-
- ins.transferTo(out)
-
- out.closeEntry()
- }
- }
- }
-
private fun processSingleClass(
inZip: ZipFile,
- entry: ZipEntry,
- outZip: ZipOutputStream,
+ entry: ZipArchiveEntry,
+ outZip: ZipArchiveOutputStream,
processor: HostStubGenClassProcessor,
stats: RavenizerStats,
) {
stats.processedClasses += 1
- val newEntry = ZipEntry(entry.name)
- outZip.putNextEntry(newEntry)
-
- BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
- var classBytes = bis.readBytes()
+ inZip.getInputStream(entry).use { zis ->
+ var classBytes = zis.readAllBytes()
stats.totalRavenizeTime += log.vTime("Ravenize ${entry.name}") {
classBytes = ravenizeSingleClass(entry, classBytes, processor.allClasses)
}
stats.totalHostStubGenTime += log.vTime("HostStubGen ${entry.name}") {
classBytes = processor.processClassBytecode(classBytes)
}
- outZip.write(classBytes)
+ // TODO: if the class does not change, use copyZipEntry
+ outZip.addBytesEntry(entry.name, classBytes)
}
- outZip.closeEntry()
}
/**
@@ -237,7 +204,7 @@ class Ravenizer {
}
private fun ravenizeSingleClass(
- entry: ZipEntry,
+ entry: ZipArchiveEntry,
input: ByteArray,
allClasses: ClassNodes,
): ByteArray {
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 35db3c6f0a6d..a133131a1d3f 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -223,6 +223,16 @@ flag {
}
flag {
+ name: "manager_lifecycle_user_change"
+ namespace: "accessibility"
+ description: "Use A11yManagerService's Lifecycle to change users, instead of listening for user changed events."
+ bug: "393626471"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "motion_event_injector_cancel_fix"
namespace: "accessibility"
description: "Fix the ACTION_CANCEL logic used in MotionEventInjector to avoid InputDispatcher inconsistency"
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 703e37fad5ad..69ea12d86d47 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -500,6 +500,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mService = new AccessibilityManagerService(context);
}
+ @VisibleForTesting
+ public Lifecycle(Context context, AccessibilityManagerService service) {
+ super(context);
+ mService = service;
+ }
+
@Override
public void onStart() {
LocalServices.addService(AccessibilityManagerInternal.class,
@@ -511,6 +517,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
public void onBootPhase(int phase) {
mService.onBootPhase(phase);
}
+
+ @Override
+ public void onUserSwitching(@androidx.annotation.Nullable TargetUser from,
+ @androidx.annotation.NonNull TargetUser to) {
+ super.onUserSwitching(from, to);
+ if (Flags.managerLifecycleUserChange()) {
+ mService.switchUser(to.getUserIdentifier());
+ }
+ }
}
private InputManager.KeyGestureEventHandler mKeyGestureEventHandler =
@@ -1055,7 +1070,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
String action = intent.getAction();
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+ if (!Flags.managerLifecycleUserChange()) {
+ switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+ }
} else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
unlockUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
diff --git a/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java b/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
index 94cef418b6c8..edcf5748a8fc 100644
--- a/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
@@ -17,6 +17,7 @@
package com.android.server.accessibility;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.Notification;
@@ -149,11 +150,7 @@ public class HearingDevicePhoneCallNotificationController {
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
- if (mIsCommDeviceChangedRegistered) {
- mIsCommDeviceChangedRegistered = false;
- mAudioManager.removeOnCommunicationDeviceChangedListener(
- mCommDeviceChangedListener);
- }
+ removeOnCommunicationDeviceChangedListenerIfNeeded(mCommDeviceChangedListener);
dismissNotificationIfNeeded();
if (mHearingDevice != null) {
@@ -172,10 +169,8 @@ public class HearingDevicePhoneCallNotificationController {
if (mHearingDevice != null) {
showNotificationIfNeeded();
} else {
- mAudioManager.addOnCommunicationDeviceChangedListener(
- mCommDeviceChangedExecutor,
+ addOnCommunicationDeviceChangedListenerIfNeeded(mCommDeviceChangedExecutor,
mCommDeviceChangedListener);
- mIsCommDeviceChangedRegistered = true;
}
} else {
mHearingDevice = getSupportedInputHearingDeviceInfo(
@@ -187,6 +182,27 @@ public class HearingDevicePhoneCallNotificationController {
}
}
+ private void addOnCommunicationDeviceChangedListenerIfNeeded(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull AudioManager.OnCommunicationDeviceChangedListener listener) {
+ if (mIsCommDeviceChangedRegistered) {
+ return;
+ }
+
+ mIsCommDeviceChangedRegistered = true;
+ mAudioManager.addOnCommunicationDeviceChangedListener(executor, listener);
+ }
+
+ private void removeOnCommunicationDeviceChangedListenerIfNeeded(
+ @NonNull AudioManager.OnCommunicationDeviceChangedListener listener) {
+ if (!mIsCommDeviceChangedRegistered) {
+ return;
+ }
+
+ mAudioManager.removeOnCommunicationDeviceChangedListener(listener);
+ mIsCommDeviceChangedRegistered = false;
+ }
+
private void showNotificationIfNeeded() {
if (mIsNotificationShown) {
return;
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index a4cbf420b93b..193d82743a34 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -788,7 +788,6 @@ public class AdbDebuggingManager {
// === Messages we can send to adbd ===========
static final String MSG_DISCONNECT_DEVICE = "DD";
- static final String MSG_DISABLE_ADBDWIFI = "DA";
@Nullable @VisibleForTesting AdbKeyStore mAdbKeyStore;
@@ -1093,9 +1092,6 @@ public class AdbDebuggingManager {
setAdbConnectionInfo(null);
mContext.unregisterReceiver(mBroadcastReceiver);
- if (mThread != null) {
- mThread.sendResponse(MSG_DISABLE_ADBDWIFI);
- }
onAdbdWifiServerDisconnected(-1);
stopAdbDebuggingThread();
break;
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 517279bd7527..8b3eb48fc783 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -98,6 +98,9 @@ public final class AppStartInfoTracker {
@VisibleForTesting static final int APP_START_INFO_HISTORY_LIST_SIZE = 16;
+ @VisibleForTesting
+ static final long APP_START_INFO_HISTORY_LENGTH_MS = TimeUnit.DAYS.toMillis(14);
+
/**
* The max number of records that can be present in {@link mInProgressRecords}.
*
@@ -120,9 +123,13 @@ public final class AppStartInfoTracker {
* Monotonic clock which does not reset on reboot.
*
* Time for offset is persisted along with records, see {@link #persistProcessStartInfo}.
- * This does not follow the recommendation of {@link MonotonicClock} to persist on shutdown as
- * it's ok in this case to lose any time change past the last persist as records added since
- * then will be lost as well and the purpose of this clock is to keep records in order.
+ * This does not currently follow the recommendation of {@link MonotonicClock} to persist on
+ * shutdown as it's ok in this case to lose any time change past the last persist as records
+ * added since then will be lost as well. Since this time is used for cleanup as well, the
+ * potential old offset may result in the cleanup window being extended slightly beyond the
+ * targeted 14 days.
+ *
+ * TODO: b/402794215 - Persist on shutdown once persist performance is sufficiently improved.
*/
@VisibleForTesting MonotonicClock mMonotonicClock = null;
@@ -296,7 +303,7 @@ public final class AppStartInfoTracker {
if (!mEnabled) {
return;
}
- ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+ ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
start.setIntent(intent);
start.setStartType(ApplicationStartInfo.START_TYPE_UNSET);
@@ -454,7 +461,7 @@ public final class AppStartInfoTracker {
if (!mEnabled) {
return;
}
- ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+ ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
addBaseFieldsFromProcessRecord(start, app);
start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
start.addStartupTimestamp(
@@ -484,7 +491,7 @@ public final class AppStartInfoTracker {
if (!mEnabled) {
return;
}
- ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+ ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
addBaseFieldsFromProcessRecord(start, app);
start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
start.addStartupTimestamp(
@@ -511,7 +518,7 @@ public final class AppStartInfoTracker {
if (!mEnabled) {
return;
}
- ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+ ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
addBaseFieldsFromProcessRecord(start, app);
start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
start.addStartupTimestamp(
@@ -533,7 +540,7 @@ public final class AppStartInfoTracker {
if (!mEnabled) {
return;
}
- ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+ ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
addBaseFieldsFromProcessRecord(start, app);
start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
start.addStartupTimestamp(
@@ -721,8 +728,8 @@ public final class AppStartInfoTracker {
Collections.sort(
list, (a, b) ->
- Long.compare(b.getMonoticCreationTimeMs(),
- a.getMonoticCreationTimeMs()));
+ Long.compare(b.getMonotonicCreationTimeMs(),
+ a.getMonotonicCreationTimeMs()));
int size = list.size();
if (maxNum > 0) {
size = Math.min(size, maxNum);
@@ -1098,7 +1105,7 @@ public final class AppStartInfoTracker {
mLastAppStartInfoPersistTimestamp = now;
}
}
- proto.write(AppsStartInfoProto.MONOTONIC_TIME, getMonotonicTime());
+ proto.write(AppsStartInfoProto.MONOTONIC_TIME, getMonotonicTimeMs());
if (succeeded) {
proto.flush();
af.finishWrite(out);
@@ -1219,7 +1226,11 @@ public final class AppStartInfoTracker {
}
}
- private long getMonotonicTime() {
+ /**
+ * Monotonic time that doesn't change with reboot or device time change for ordering records.
+ */
+ @VisibleForTesting
+ public long getMonotonicTimeMs() {
if (mMonotonicClock == null) {
// This should never happen. Return 0 to not interfere with past or future records.
return 0;
@@ -1229,7 +1240,7 @@ public final class AppStartInfoTracker {
/** A container class of (@link android.app.ApplicationStartInfo) */
final class AppStartInfoContainer {
- private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
+ private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by monotonic time.
private int mMaxCapacity;
private int mUid;
private boolean mMonitoringModeEnabled = false;
@@ -1260,9 +1271,12 @@ public final class AppStartInfoTracker {
return;
}
- // Sort records so we can remove the least recent ones.
- Collections.sort(mInfos, (a, b) ->
- Long.compare(b.getMonoticCreationTimeMs(), a.getMonoticCreationTimeMs()));
+ if (!android.app.Flags.appStartInfoKeepRecordsSorted()) {
+ // Sort records so we can remove the least recent ones.
+ Collections.sort(mInfos, (a, b) ->
+ Long.compare(b.getMonotonicCreationTimeMs(),
+ a.getMonotonicCreationTimeMs()));
+ }
// Remove records and trim list object back to size.
mInfos.subList(0, mInfos.size() - getMaxCapacity()).clear();
@@ -1277,25 +1291,34 @@ public final class AppStartInfoTracker {
@GuardedBy("mLock")
void addStartInfoLocked(ApplicationStartInfo info) {
- int size = mInfos.size();
- if (size >= getMaxCapacity()) {
- // Remove oldest record if size is over max capacity.
- int oldestIndex = -1;
- long oldestTimeStamp = Long.MAX_VALUE;
- for (int i = 0; i < size; i++) {
- ApplicationStartInfo startInfo = mInfos.get(i);
- if (startInfo.getMonoticCreationTimeMs() < oldestTimeStamp) {
- oldestTimeStamp = startInfo.getMonoticCreationTimeMs();
- oldestIndex = i;
- }
+ if (android.app.Flags.appStartInfoKeepRecordsSorted()) {
+ while (mInfos.size() >= getMaxCapacity()) {
+ // Expected to execute at most once.
+ mInfos.removeLast();
}
- if (oldestIndex >= 0) {
- mInfos.remove(oldestIndex);
+ mInfos.addFirst(info);
+ } else {
+ int size = mInfos.size();
+ if (size >= getMaxCapacity()) {
+ // Remove oldest record if size is over max capacity.
+ int oldestIndex = -1;
+ long oldestTimeStamp = Long.MAX_VALUE;
+ for (int i = 0; i < size; i++) {
+ ApplicationStartInfo startInfo = mInfos.get(i);
+ if (startInfo.getMonotonicCreationTimeMs() < oldestTimeStamp) {
+ oldestTimeStamp = startInfo.getMonotonicCreationTimeMs();
+ oldestIndex = i;
+ }
+ }
+ if (oldestIndex >= 0) {
+ mInfos.remove(oldestIndex);
+ }
}
+ mInfos.add(info);
+ Collections.sort(mInfos, (a, b) ->
+ Long.compare(b.getMonotonicCreationTimeMs(),
+ a.getMonotonicCreationTimeMs()));
}
- mInfos.add(info);
- Collections.sort(mInfos, (a, b) ->
- Long.compare(b.getMonoticCreationTimeMs(), a.getMonoticCreationTimeMs()));
}
/**
@@ -1439,9 +1462,25 @@ public final class AppStartInfoTracker {
long token = proto.start(fieldId);
proto.write(AppsStartInfoProto.Package.User.UID, mUid);
int size = mInfos.size();
- for (int i = 0; i < size; i++) {
- mInfos.get(i).writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
- byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+ if (android.app.Flags.appStartInfoCleanupOldRecords()) {
+ long removeOlderThan = getMonotonicTimeMs() - APP_START_INFO_HISTORY_LENGTH_MS;
+ // Iterate backwards so we can remove old records as we go.
+ for (int i = size - 1; i >= 0; i--) {
+ if (mInfos.get(i).getMonotonicCreationTimeMs() < removeOlderThan) {
+ // Remove the record.
+ mInfos.remove(i);
+ } else {
+ mInfos.get(i).writeToProto(
+ proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+ }
+ }
+ } else {
+ for (int i = 0; i < size; i++) {
+ mInfos.get(i).writeToProto(
+ proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+ byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+ }
}
proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
proto.end(token);
@@ -1466,7 +1505,13 @@ public final class AppStartInfoTracker {
info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
byteArrayInputStream, objectInputStream, typedXmlPullParser);
info.setPackageName(packageName);
- mInfos.add(info);
+ if (android.app.Flags.appStartInfoKeepRecordsSorted()) {
+ // Since the writes are done from oldest to newest, each additional
+ // record will be newer than the previous so use addFirst.
+ mInfos.addFirst(info);
+ } else {
+ mInfos.add(info);
+ }
break;
case (int) AppsStartInfoProto.Package.User.MONITORING_ENABLED:
mMonitoringModeEnabled = proto.readBoolean(
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a61368c4bc36..ad47e67b9332 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -793,6 +793,7 @@ public final class ProcessList {
final ProcessMap<ProcessRecord> mDyingProcesses = new ProcessMap<>();
// Self locked with the inner lock within the RemoteCallbackList
+ @GuardedBy("mProcessObservers")
private final RemoteCallbackList<IProcessObserver> mProcessObservers =
new RemoteCallbackList<>();
@@ -4980,11 +4981,15 @@ public final class ProcessList {
}
void registerProcessObserver(IProcessObserver observer) {
- mProcessObservers.register(observer);
+ synchronized (mProcessObservers) {
+ mProcessObservers.register(observer);
+ }
}
void unregisterProcessObserver(IProcessObserver observer) {
- mProcessObservers.unregister(observer);
+ synchronized (mProcessObservers) {
+ mProcessObservers.unregister(observer);
+ }
}
void dispatchProcessesChanged() {
@@ -5002,38 +5007,41 @@ public final class ProcessList {
}
}
- int i = mProcessObservers.beginBroadcast();
- while (i > 0) {
- i--;
- final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
- if (observer != null) {
- try {
- for (int j = 0; j < numOfChanges; j++) {
- ProcessChangeItem item = mActiveProcessChanges[j];
- if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
- if (DEBUG_PROCESS_OBSERVERS) {
- Slog.i(TAG_PROCESS_OBSERVERS,
- "ACTIVITIES CHANGED pid=" + item.pid + " uid="
- + item.uid + ": " + item.foregroundActivities);
+ synchronized (mProcessObservers) {
+ int i = mProcessObservers.beginBroadcast();
+ while (i > 0) {
+ i--;
+ final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
+ if (observer != null) {
+ try {
+ for (int j = 0; j < numOfChanges; j++) {
+ ProcessChangeItem item = mActiveProcessChanges[j];
+ if ((item.changes & ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
+ if (DEBUG_PROCESS_OBSERVERS) {
+ Slog.i(TAG_PROCESS_OBSERVERS,
+ "ACTIVITIES CHANGED pid=" + item.pid + " uid="
+ + item.uid + ": " + item.foregroundActivities);
+ }
+ observer.onForegroundActivitiesChanged(item.pid, item.uid,
+ item.foregroundActivities);
}
- observer.onForegroundActivitiesChanged(item.pid, item.uid,
- item.foregroundActivities);
- }
- if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES) != 0) {
- if (DEBUG_PROCESS_OBSERVERS) {
- Slog.i(TAG_PROCESS_OBSERVERS,
- "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid="
- + item.uid + ": " + item.foregroundServiceTypes);
+ if ((item.changes & ProcessChangeItem.CHANGE_FOREGROUND_SERVICES)
+ != 0) {
+ if (DEBUG_PROCESS_OBSERVERS) {
+ Slog.i(TAG_PROCESS_OBSERVERS,
+ "FOREGROUND SERVICES CHANGED pid=" + item.pid + " uid="
+ + item.uid + ": " + item.foregroundServiceTypes);
+ }
+ observer.onForegroundServicesChanged(item.pid, item.uid,
+ item.foregroundServiceTypes);
}
- observer.onForegroundServicesChanged(item.pid, item.uid,
- item.foregroundServiceTypes);
}
+ } catch (RemoteException e) {
}
- } catch (RemoteException e) {
}
}
+ mProcessObservers.finishBroadcast();
}
- mProcessObservers.finishBroadcast();
synchronized (mProcessChangeLock) {
for (int j = 0; j < numOfChanges; j++) {
@@ -5122,22 +5130,42 @@ public final class ProcessList {
}
void dispatchProcessStarted(ProcessRecord app, int pid) {
- // TODO(b/323959187) Add the implementation.
+ if (!android.app.Flags.enableProcessObserverBroadcastOnProcessStarted()) {
+ Slog.i(TAG, "ProcessObserver broadcast disabled");
+ return;
+ }
+ synchronized (mProcessObservers) {
+ int i = mProcessObservers.beginBroadcast();
+ while (i > 0) {
+ i--;
+ final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
+ if (observer != null) {
+ try {
+ observer.onProcessStarted(pid, app.uid, app.info.uid,
+ app.info.packageName, app.processName);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ mProcessObservers.finishBroadcast();
+ }
}
void dispatchProcessDied(int pid, int uid) {
- int i = mProcessObservers.beginBroadcast();
- while (i > 0) {
- i--;
- final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
- if (observer != null) {
- try {
- observer.onProcessDied(pid, uid);
- } catch (RemoteException e) {
+ synchronized (mProcessObservers) {
+ int i = mProcessObservers.beginBroadcast();
+ while (i > 0) {
+ i--;
+ final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
+ if (observer != null) {
+ try {
+ observer.onProcessDied(pid, uid);
+ } catch (RemoteException e) {
+ }
}
}
+ mProcessObservers.finishBroadcast();
}
- mProcessObservers.finishBroadcast();
}
@GuardedBy(anyOf = {"mService", "mProcLock"})
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index cb4342f27bc8..c2ed4d557e69 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -256,6 +256,7 @@ public class SettingsToPropertiesMapper {
"pixel_vpn",
"pixel_watch",
"pixel_watch_debug_trace",
+ "pixel_watch_watchfaces",
"pixel_wifi",
"platform_compat",
"platform_security",
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index bf7f1946531c..6b3661a2a004 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -929,7 +929,8 @@ public class AudioService extends IAudioService.Stub
private final Object mAbsoluteVolumeDeviceInfoMapLock = new Object();
// Devices where the framework sends a full scale audio signal, and controls the volume of
// the external audio system separately.
- // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+ // For possible volume behaviors, see
+ // {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
@GuardedBy("mAbsoluteVolumeDeviceInfoMapLock")
Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
@@ -942,7 +943,7 @@ public class AudioService extends IAudioService.Stub
private final List<VolumeInfo> mVolumeInfos;
private final IAudioDeviceVolumeDispatcher mCallback;
private final boolean mHandlesVolumeAdjustment;
- private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
+ private @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
private AbsoluteVolumeDeviceInfo(
AudioService parent,
@@ -950,7 +951,7 @@ public class AudioService extends IAudioService.Stub
List<VolumeInfo> volumeInfos,
IAudioDeviceVolumeDispatcher callback,
boolean handlesVolumeAdjustment,
- @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+ @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior) {
this.mParent = parent;
this.mDevice = device;
this.mVolumeInfos = volumeInfos;
@@ -8173,7 +8174,7 @@ public class AudioService extends IAudioService.Stub
IAudioDeviceVolumeDispatcher cb, String packageName,
AudioDeviceAttributes device, List<VolumeInfo> volumes,
boolean handlesVolumeAdjustment,
- @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
+ @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
// verify permissions
if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
!= PackageManager.PERMISSION_GRANTED
@@ -8240,12 +8241,13 @@ public class AudioService extends IAudioService.Stub
@android.annotation.EnforcePermission(anyOf = {
MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
+ @Nullable String pkgName) {
// verify permissions
super.setDeviceVolumeBehavior_enforcePermission();
// verify arguments
Objects.requireNonNull(device);
- AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
+ AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
device = retrieveBluetoothAddress(device);
@@ -8268,7 +8270,8 @@ public class AudioService extends IAudioService.Stub
}
private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
+ @NonNull String caller) {
int audioSystemDeviceOut = device.getInternalType();
boolean volumeBehaviorChanged = false;
// update device masks based on volume behavior
@@ -8323,7 +8326,7 @@ public class AudioService extends IAudioService.Stub
@android.annotation.EnforcePermission(anyOf = {
MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE, MODIFY_AUDIO_SETTINGS_PRIVILEGED
})
- public @AudioManager.DeviceVolumeBehavior
+ public @AudioDeviceVolumeManager.DeviceVolumeBehavior
int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
// verify permissions
super.getDeviceVolumeBehavior_enforcePermission();
@@ -8335,7 +8338,7 @@ public class AudioService extends IAudioService.Stub
return getDeviceVolumeBehaviorInt(device);
}
- private @AudioManager.DeviceVolumeBehavior
+ private @AudioDeviceVolumeManager.DeviceVolumeBehavior
int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
// Get the internal type set by the AudioDeviceAttributes constructor which is always more
// exact (avoids double conversions) than a conversion from SDK type via
@@ -15354,7 +15357,8 @@ public class AudioService extends IAudioService.Stub
/**
* Returns whether the input device uses absolute volume behavior, including its variants.
- * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+ * For included volume behaviors, see
+ * {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
* <p>This is distinct from Bluetooth A2DP absolute volume behavior
* ({@link #isA2dpAbsoluteVolumeDevice}).
*/
@@ -15381,7 +15385,7 @@ public class AudioService extends IAudioService.Stub
}
private void persistDeviceVolumeBehavior(int deviceType,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
if (DEBUG_VOL) {
Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
}
@@ -15396,7 +15400,7 @@ public class AudioService extends IAudioService.Stub
}
}
- @AudioManager.DeviceVolumeBehaviorState
+ @AudioDeviceVolumeManager.DeviceVolumeBehaviorState
private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
return mSettings.getSystemIntForUser(mContentResolver,
getSettingsNameForDeviceVolumeBehavior(deviceType),
diff --git a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
index ab86433ca50d..62c3dbd3df8c 100644
--- a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
@@ -23,6 +23,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
import android.media.VolumeInfo;
import java.util.concurrent.Executor;
@@ -53,7 +54,7 @@ public interface AudioDeviceVolumeManagerWrapper {
/**
* Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior(
- * AudioDeviceAttributes, VolumeInfo, Executor, OnAudioDeviceVolumeChangedListener, boolean)}
+ * AudioDeviceAttributes, VolumeInfo, boolean, Executor, OnAudioDeviceVolumeChangedListener)}
*/
void setDeviceAbsoluteVolumeBehavior(
@NonNull AudioDeviceAttributes device,
@@ -64,7 +65,7 @@ public interface AudioDeviceVolumeManagerWrapper {
/**
* Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeAdjustOnlyBehavior(
- * AudioDeviceAttributes, VolumeInfo, Executor, OnAudioDeviceVolumeChangedListener, boolean)}
+ * AudioDeviceAttributes, VolumeInfo, boolean, Executor, OnAudioDeviceVolumeChangedListener)}
*/
void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
@NonNull AudioDeviceAttributes device,
@@ -72,4 +73,16 @@ public interface AudioDeviceVolumeManagerWrapper {
boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
@NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener);
+
+ /**
+ * Wraps {@link AudioDeviceVolumeManager#getDeviceVolumeBehavior(AudioDeviceAttributes)}
+ */
+ @AudioManager.DeviceVolumeBehavior
+ int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device);
+
+ /**
+ * Wraps {@link AudioDeviceVolumeManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)}
+ */
+ void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior);
}
diff --git a/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
index fd4dd516fd51..6d01e2da3e9d 100644
--- a/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
@@ -85,18 +85,6 @@ public interface AudioManagerWrapper {
void setWiredDeviceConnectionState(int device, int state, String address, String name);
/**
- * Wraps {@link AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)}
- */
- @AudioManager.DeviceVolumeBehavior
- int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device);
-
- /**
- * Wraps {@link AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)}
- */
- void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior);
-
- /**
* Wraps {@link AudioManager#getDevicesForAttributes(AudioAttributes)}
*/
@NonNull
diff --git a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
index 10cbb00d2398..02d8579f738f 100644
--- a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
@@ -16,11 +16,14 @@
package com.android.server.hdmi;
+import static android.media.audio.Flags.unifyAbsoluteVolumeManagement;
+
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.content.Context;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
import android.media.VolumeInfo;
import java.util.concurrent.Executor;
@@ -38,9 +41,11 @@ public class DefaultAudioDeviceVolumeManagerWrapper
private static final String TAG = "AudioDeviceVolumeManagerWrapper";
private final AudioDeviceVolumeManager mAudioDeviceVolumeManager;
+ private final AudioManager mAudioManager;
public DefaultAudioDeviceVolumeManagerWrapper(Context context) {
mAudioDeviceVolumeManager = new AudioDeviceVolumeManager(context);
+ mAudioManager = context.getSystemService(AudioManager.class);
}
@Override
@@ -78,4 +83,24 @@ public class DefaultAudioDeviceVolumeManagerWrapper
mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeAdjustOnlyBehavior(device, volume,
handlesVolumeAdjustment, executor, vclistener);
}
+
+ @Override
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior
+ public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
+ if (!unifyAbsoluteVolumeManagement()) {
+ int deviceBehavior = mAudioManager.getDeviceVolumeBehavior(device);
+ return deviceBehavior;
+ }
+ return mAudioDeviceVolumeManager.getDeviceVolumeBehavior(device);
+ }
+
+ @Override
+ public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+ if (!unifyAbsoluteVolumeManagement()) {
+ int deviceBehavior = deviceVolumeBehavior;
+ mAudioManager.setDeviceVolumeBehavior(device, deviceBehavior);
+ }
+ mAudioDeviceVolumeManager.setDeviceVolumeBehavior(device, deviceVolumeBehavior);
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java b/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
index 061e145c27f3..662715420ec6 100644
--- a/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
@@ -94,18 +94,6 @@ public class DefaultAudioManagerWrapper implements AudioManagerWrapper {
}
@Override
- @AudioManager.DeviceVolumeBehavior
- public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
- return mAudioManager.getDeviceVolumeBehavior(device);
- }
-
- @Override
- public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
- mAudioManager.setDeviceVolumeBehavior(device, deviceVolumeBehavior);
- }
-
- @Override
@NonNull
public List<AudioDeviceAttributes> getDevicesForAttributes(
@NonNull AudioAttributes attributes) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index fdd0ef2f90e1..41b0b4dc716a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4595,7 +4595,7 @@ public class HdmiControlService extends SystemService {
* Wrapper for {@link AudioManager#getDeviceVolumeBehavior} that takes advantage of cached
* results for the volume behaviors of HDMI audio devices.
*/
- @AudioManager.DeviceVolumeBehavior
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior
private int getDeviceVolumeBehavior(AudioDeviceAttributes device) {
if (AVB_AUDIO_OUTPUT_DEVICES.contains(device)) {
synchronized (mLock) {
@@ -4604,7 +4604,7 @@ public class HdmiControlService extends SystemService {
}
}
}
- return getAudioManager().getDeviceVolumeBehavior(device);
+ return getAudioDeviceVolumeManager().getDeviceVolumeBehavior(device);
}
/**
@@ -4695,7 +4695,7 @@ public class HdmiControlService extends SystemService {
// Condition 3: All AVB-capable audio outputs already use full/absolute volume behavior
// We only need to check the first AVB-capable audio output because only TV panels
// have more than one of them, and they always have the same volume behavior.
- @AudioManager.DeviceVolumeBehavior int currentVolumeBehavior =
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int currentVolumeBehavior =
getDeviceVolumeBehavior(getAvbCapableAudioOutputDevices().get(0));
boolean alreadyUsingFullOrAbsoluteVolume =
FULL_AND_ABSOLUTE_VOLUME_BEHAVIORS.contains(currentVolumeBehavior);
@@ -4719,7 +4719,8 @@ public class HdmiControlService extends SystemService {
// Condition 5: The System Audio device supports <Set Audio Volume Level>
switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
case DeviceFeatures.FEATURE_SUPPORTED:
- if (currentVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ if (currentVolumeBehavior
+ != AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
// Start an action that will call enableAbsoluteVolumeBehavior
// once the System Audio device sends <Report Audio Status>
localCecDevice.startNewAvbAudioStatusAction(
@@ -4731,13 +4732,15 @@ public class HdmiControlService extends SystemService {
// This allows the device to display numeric volume UI for the System Audio device.
if (tv() != null && mNumericSoundbarVolumeUiOnTvFeatureFlagEnabled) {
if (currentVolumeBehavior
- != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
+ != AudioDeviceVolumeManager
+ .DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
// If we're currently using absolute volume behavior, switch to full volume
// behavior until we successfully adopt adjust-only absolute volume behavior
- if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ if (currentVolumeBehavior
+ == AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
- getAudioManager().setDeviceVolumeBehavior(device,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ getAudioDeviceVolumeManager().setDeviceVolumeBehavior(device,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
}
// Start an action that will call enableAbsoluteVolumeBehavior
@@ -4750,7 +4753,8 @@ public class HdmiControlService extends SystemService {
}
return;
case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
- if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+ if (currentVolumeBehavior
+ == AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
switchToFullVolumeBehavior();
}
localCecDevice.querySetAudioVolumeLevelSupport(
@@ -4773,8 +4777,8 @@ public class HdmiControlService extends SystemService {
for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
if (ABSOLUTE_VOLUME_BEHAVIORS.contains(getDeviceVolumeBehavior(device))) {
- getAudioManager().setDeviceVolumeBehavior(device,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ getAudioDeviceVolumeManager().setDeviceVolumeBehavior(device,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a8190269450a..07d1a65850e3 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1917,7 +1917,7 @@ public class LockSettingsService extends ILockSettings.Stub {
* Set a new LSKF for the given user/profile. Only succeeds if the synthetic password for the
* user is protected by the given {@param savedCredential}.
* <p>
- * When {@link android.security.Flags#clearStrongAuthOnAddPrimaryCredential()} is enabled and
+ * When {@link android.security.Flags#clearStrongAuthOnAddingPrimaryCredential()} is enabled and
* setting a new credential where there was none, updates the strong auth state for
* {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>.
*
@@ -1969,7 +1969,7 @@ public class LockSettingsService extends ILockSettings.Stub {
onSyntheticPasswordUnlocked(userId, sp);
setLockCredentialWithSpLocked(credential, sp, userId);
- if (android.security.Flags.clearStrongAuthOnAddPrimaryCredential()
+ if (android.security.Flags.clearStrongAuthOnAddingPrimaryCredential()
&& savedCredential.isNone() && !credential.isNone()) {
// Clear the strong auth value, since the LSKF has just been entered and set,
// but only when the previous credential was None.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 78554bdcf6aa..06fc9b083086 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -14544,23 +14544,23 @@ public class NotificationManagerService extends SystemService {
*/
private class NotificationTrampolineCallback implements BackgroundActivityStartCallback {
@Override
- public boolean isActivityStartAllowed(Collection<IBinder> tokens, int uid,
- String packageName) {
+ public BackgroundActivityStartCallbackResult isActivityStartAllowed(
+ Collection<IBinder> tokens, int uid, String packageName) {
checkArgument(!tokens.isEmpty());
for (IBinder token : tokens) {
if (token != ALLOWLIST_TOKEN) {
// We only block or warn if the start is exclusively due to notification
- return true;
+ return RESULT_TRUE;
}
}
String logcatMessage =
"Indirect notification activity start (trampoline) from " + packageName;
if (blockTrampoline(uid)) {
Slog.e(TAG, logcatMessage + " blocked");
- return false;
+ return RESULT_FALSE;
} else {
Slog.w(TAG, logcatMessage + ", this should be avoided for performance reasons");
- return true;
+ return new BackgroundActivityStartCallbackResult(true, ALLOWLIST_TOKEN);
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 233b577e1c61..33a7e7476cf6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -7724,6 +7724,7 @@ public class UserManagerService extends IUserManager.Stub {
pw.print(" Has profile owner: ");
pw.println(mIsUserManaged.get(userId));
+
pw.println(" Restrictions:");
synchronized (mRestrictionsLock) {
UserRestrictionsUtils.dumpRestrictions(
@@ -7756,6 +7757,9 @@ public class UserManagerService extends IUserManager.Stub {
}
}
+ pw.print(" Can have profile: ");
+ pw.println(userInfo.canHaveProfile());
+
if (userData.userProperties != null) {
userData.userProperties.println(pw, " ");
}
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 f5daa8036726..8c3b7c606f04 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -17,11 +17,13 @@
package com.android.server.security.advancedprotection;
import static android.provider.Settings.Secure.ADVANCED_PROTECTION_MODE;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import android.Manifest;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.StatsManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Binder;
@@ -45,6 +47,7 @@ import android.security.advancedprotection.IAdvancedProtectionService;
import android.security.advancedprotection.AdvancedProtectionProtoEnums;
import android.util.ArrayMap;
import android.util.Slog;
+import android.util.StatsEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
@@ -137,6 +140,15 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
mProviders.add(new DisallowWepAdvancedProtectionProvider());
}
+ private void initLogging() {
+ StatsManager statsManager = mContext.getSystemService(StatsManager.class);
+ statsManager.setPullAtomCallback(
+ FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR,
+ new AdvancedProtectionStatePullAtomCallback());
+ }
+
// Only for tests
@VisibleForTesting
AdvancedProtectionService(@NonNull Context context, @NonNull AdvancedProtectionStore store,
@@ -399,6 +411,7 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
Slog.i(TAG, "Advanced protection is enabled");
}
mService.initFeatures(enabled);
+ mService.initLogging();
}
}
}
@@ -500,4 +513,22 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
}
}
+
+ private class AdvancedProtectionStatePullAtomCallback
+ implements StatsManager.StatsPullAtomCallback {
+
+ @Override
+ public int onPullAtom(int atomTag, List<StatsEvent> data) {
+ if (atomTag != FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ data.add(
+ FrameworkStatsLog.buildStatsEvent(
+ FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO,
+ /*enabled*/ isAdvancedProtectionEnabledInternal(),
+ /*hours_since_enabled*/ hoursSinceLastChange()));
+ return StatsManager.PULL_SUCCESS;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 424439df3c4b..e22bc7d0719e 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -863,7 +863,7 @@ public class WallpaperCropper {
double maxDisplayToImageRatio = Math.max((double) displaySize.x / croppedImageBound.width(),
(double) displaySize.y / croppedImageBound.height());
- if (maxDisplayToImageRatio > 1.3) {
+ if (maxDisplayToImageRatio > 1.5) {
return false;
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
index f413fe33c3f2..58f34d0404d0 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
@@ -36,7 +36,4 @@ public abstract class WallpaperManagerInternal {
/** Notifies when the screen starts turning on and is not yet visible to the user. */
public abstract void onScreenTurningOn(int displayId);
-
- /** Notifies when the keyguard is going away. Sent right after the bouncer is gone. */
- public abstract void onKeyguardGoingAway();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e7da33d50b27..274175aa71ba 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.Flags.fixWallpaperChanged;
import static android.app.Flags.liveWallpaperContentHandling;
+import static android.app.Flags.notifyKeyguardEvents;
import static android.app.Flags.removeNextWallpaperComponent;
import static android.app.WallpaperManager.COMMAND_REAPPLY;
import static android.app.WallpaperManager.FLAG_LOCK;
@@ -1709,8 +1710,32 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper,
mWallpaperCropper);
LocalServices.addService(WallpaperManagerInternal.class, new LocalService());
+
+ LocalServices.getService(ActivityTaskManagerInternal.class)
+ .registerScreenObserver(mKeyguardObserver);
+
}
+ private final ActivityTaskManagerInternal.ScreenObserver mKeyguardObserver =
+ new ActivityTaskManagerInternal.ScreenObserver() {
+ @Override
+ public void onKeyguardStateChanged(boolean isShowing) {
+ if (!notifyKeyguardEvents()) {
+ return;
+ }
+ if (isShowing) {
+ notifyKeyguardAppearing();
+ } else {
+ notifyKeyguardGoingAway();
+ }
+ }
+
+ @Override
+ public void onKeyguardGoingAway() {
+ notifyKeyguardGoingAway();
+ }
+ };
+
private final class LocalService extends WallpaperManagerInternal {
@Override
public void onDisplayAddSystemDecorations(int displayId) {
@@ -1733,11 +1758,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
public void onScreenTurningOn(int displayId) {
notifyScreenTurningOn(displayId);
}
-
- @Override
- public void onKeyguardGoingAway() {
- notifyKeyguardGoingAway();
- }
}
void initialize() {
@@ -2571,6 +2591,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
}
+ private boolean hasPermission(WallpaperData data, String permission) {
+ try {
+ return PackageManager.PERMISSION_GRANTED == mIPackageManager.checkPermission(
+ permission,
+ data.getComponent().getPackageName(),
+ data.userId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to check wallpaper service permission", e);
+ return false;
+ }
+ }
+
private boolean hasAppOpPermission(String permission, int callingUid, String callingPackage,
String attributionTag, String message) {
final String op = AppOpsManager.permissionToOp(permission);
@@ -2873,16 +2905,37 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
* Propagate a keyguard going away event to the wallpaper engine.
*/
private void notifyKeyguardGoingAway() {
+ dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY);
+ }
+
+ /**
+ * Propagate a keyguard appearing event to the wallpaper engine.
+ */
+ private void notifyKeyguardAppearing() {
+ dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_APPEARING);
+ }
+
+ /**
+ * Propagate a keyguard-related event to the wallpaper engine.
+ *
+ * When the flag below is enabled, the event will only be dispatched in case the recipient
+ * has {@link android.Manifest.pertmission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} permission.
+ */
+ private void dispatchKeyguardCommand(String command) {
synchronized (mLock) {
for (WallpaperData data : getActiveWallpapers()) {
+ if (notifyKeyguardEvents() && !hasPermission(
+ data, android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)) {
+ continue;
+ }
+
data.connection.forEachDisplayConnector(displayConnector -> {
if (displayConnector.mEngine != null) {
try {
displayConnector.mEngine.dispatchWallpaperCommand(
- WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY,
- -1, -1, -1, new Bundle());
+ command, -1, -1, -1, new Bundle());
} catch (RemoteException e) {
- Slog.w(TAG, "Failed to notify that the keyguard is going away", e);
+ Slog.w(TAG, "Failed to dispatch wallpaper command: " + command, e);
}
}
});
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index a731bf7c64b3..70fc6bace868 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -82,6 +82,7 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
*/
@VisibleForTesting
static final int SNAPSHOT_MODE_NONE = 2;
+ static final float THEME_SNAPSHOT_MIN_Length = 128.0f;
protected final WindowManagerService mService;
protected final float mHighResSnapshotScale;
@@ -436,14 +437,21 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
final Rect taskBounds = source.getBounds();
final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride();
final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState);
+ final int taskWidth = taskBounds.width();
+ final int taskHeight = taskBounds.height();
+ float scale = mHighResSnapshotScale;
+ if (Flags.reduceTaskSnapshotMemoryUsage()) {
+ final int minLength = Math.min(taskWidth, taskHeight);
+ if (THEME_SNAPSHOT_MIN_Length < minLength) {
+ scale = Math.min(THEME_SNAPSHOT_MIN_Length / minLength, scale);
+ }
+ }
final SnapshotDrawerUtils.SystemBarBackgroundPainter
decorPainter = new SnapshotDrawerUtils.SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.insetsFlags.appearance, taskDescription,
- mHighResSnapshotScale, mainWindow.getRequestedVisibleTypes());
- final int taskWidth = taskBounds.width();
- final int taskHeight = taskBounds.height();
- final int width = (int) (taskWidth * mHighResSnapshotScale);
- final int height = (int) (taskHeight * mHighResSnapshotScale);
+ scale, mainWindow.getRequestedVisibleTypes());
+ final int width = (int) (taskWidth * scale);
+ final int height = (int) (taskHeight * scale);
final RenderNode node = RenderNode.create("SnapshotController", null);
node.setLeftTopRightBottom(0, 0, width, height);
node.setClipToBounds(false);
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 5cc186c40b6c..a19f4388a7c8 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -272,6 +272,12 @@ class ActivityStartInterceptor {
mActivityOptions = interceptResult.getActivityOptions();
mCallingPid = mRealCallingPid;
mCallingUid = mRealCallingUid;
+ // When an activity launch is intercepted, Intent#prepareToLeaveProcess is not called
+ // since the interception happens in the system_server. So if any activity is calling
+ // a trampoline activity, the keys do not get collected. Since all the interceptors
+ // are present in the system_server, add the creator token before launching the
+ // intercepted intent.
+ mService.mAmInternal.addCreatorToken(mIntent, mCallingPackage);
if (interceptResult.isActivityResolved()) {
return true;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index c243cdc23137..21b730e13585 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -124,8 +124,9 @@ public abstract class ActivityTaskManagerInternal {
public static final String ASSIST_KEY_RECEIVER_EXTRAS = "receiverExtras";
public interface ScreenObserver {
- void onAwakeStateChanged(boolean isAwake);
- void onKeyguardStateChanged(boolean isShowing);
+ default void onAwakeStateChanged(boolean isAwake) {}
+ default void onKeyguardStateChanged(boolean isShowing) {}
+ default void onKeyguardGoingAway() {}
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 9c9656671519..46d24b0d3201 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -281,7 +281,6 @@ import com.android.server.sdksandbox.SdkSandboxManagerLocal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
-import com.android.server.wallpaper.WallpaperManagerInternal;
import com.android.server.wm.utils.WindowStyleCache;
import com.android.wm.shell.Flags;
@@ -373,7 +372,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private ComponentName mSysUiServiceComponent;
private PermissionPolicyInternal mPermissionPolicyInternal;
private StatusBarManagerInternal mStatusBarManagerInternal;
- private WallpaperManagerInternal mWallpaperManagerInternal;
private UserManagerInternal mUserManagerInternal;
@VisibleForTesting
final ActivityTaskManagerInternal mInternal;
@@ -3719,10 +3717,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (isPowerModePreApplied && !foundResumed) {
endPowerMode(POWER_MODE_REASON_START_ACTIVITY);
}
- }
- WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
- if (wallpaperManagerInternal != null) {
- wallpaperManagerInternal.onKeyguardGoingAway();
+
+ mH.post(() -> {
+ for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+ mScreenObservers.get(i).onKeyguardGoingAway();
+ }
+ });
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -5573,13 +5573,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return mStatusBarManagerInternal;
}
- WallpaperManagerInternal getWallpaperManagerInternal() {
- if (mWallpaperManagerInternal == null) {
- mWallpaperManagerInternal = LocalServices.getService(WallpaperManagerInternal.class);
- }
- return mWallpaperManagerInternal;
- }
-
UserManagerInternal getUserManagerInternal() {
if (mUserManagerInternal == null) {
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java b/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
index eec648dae24a..826d5fb1c333 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
@@ -24,6 +24,16 @@ import java.util.Collection;
* Callback to decide activity starts and related operations based on originating tokens.
*/
public interface BackgroundActivityStartCallback {
+ BackgroundActivityStartCallbackResult RESULT_FALSE =
+ new BackgroundActivityStartCallbackResult(false, null);
+ BackgroundActivityStartCallbackResult RESULT_TRUE =
+ new BackgroundActivityStartCallbackResult(true, null);
+
+ record BackgroundActivityStartCallbackResult(
+ boolean allowed,
+ IBinder token
+ ) {}
+
/**
* Returns true if the background activity start originating from {@code tokens} should be
* allowed or not.
@@ -34,7 +44,8 @@ public interface BackgroundActivityStartCallback {
* This will be called holding the WM and local lock, don't do anything costly or invoke AM/WM
* methods here directly.
*/
- boolean isActivityStartAllowed(Collection<IBinder> tokens, int uid, String packageName);
+ BackgroundActivityStartCallbackResult isActivityStartAllowed(Collection<IBinder> tokens,
+ int uid, String packageName);
/**
* Returns whether {@code uid} can send {@link android.content.Intent
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index f50a68cc5389..f8a50b3fda04 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -51,6 +51,7 @@ import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreat
import static com.android.window.flags.Flags.balShowToastsBlocked;
import static com.android.window.flags.Flags.balStrictModeGracePeriod;
import static com.android.window.flags.Flags.balStrictModeRo;
+import static com.android.window.flags.Flags.balAdditionalLogging;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import static java.util.Objects.requireNonNull;
@@ -1939,6 +1940,7 @@ public class BackgroundActivityStartController {
}
}
logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
+ logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_TOKEN);
if (balImprovedMetrics()) {
if (shouldLogStats(finalVerdict, state)) {
@@ -1998,8 +2000,10 @@ public class BackgroundActivityStartController {
return false;
} else {
// log to determine grace period length distribution
- Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " "
- + finalVerdict.mMessage + ": " + state);
+ if (balAdditionalLogging()) {
+ Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " "
+ + finalVerdict.mMessage + ": " + state);
+ }
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
index 31b239421baf..2605310db6f4 100644
--- a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
+++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
@@ -128,11 +128,16 @@ class BackgroundLaunchProcessController {
return new BalVerdict(BAL_ALLOW_PERMISSION, /*background*/
"process instrumenting with background activity starts privileges");
}
- // Allow if the flag was explicitly set.
- if (checkConfiguration.checkOtherExemptions && isBackgroundStartAllowedByToken(uid,
- packageName, checkConfiguration.isCheckingForFgsStart)) {
- return new BalVerdict(balImprovedMetrics() ? BAL_ALLOW_TOKEN : BAL_ALLOW_PERMISSION,
- /*background*/ "process allowed by token");
+ // Allow if the token is explicitly allowed.
+ if (checkConfiguration.checkOtherExemptions) {
+ BalVerdict tokenVerdict = isBackgroundStartAllowedByToken(uid,
+ packageName, checkConfiguration.isCheckingForFgsStart);
+ if (tokenVerdict.allows()) {
+ if (!balImprovedMetrics()) {
+ return new BalVerdict(BAL_ALLOW_PERMISSION, tokenVerdict.toString());
+ }
+ return tokenVerdict;
+ }
}
// Allow if the caller is bound by a UID that's currently foreground.
// But still respect the appSwitchState.
@@ -174,42 +179,53 @@ class BackgroundLaunchProcessController {
* isCheckingForFgsStart is false, we ask the callback if the start is allowed for these tokens,
* otherwise if there is no callback we allow.
*/
- private boolean isBackgroundStartAllowedByToken(int uid, String packageName,
+ private BalVerdict isBackgroundStartAllowedByToken(int uid, String packageName,
boolean isCheckingForFgsStart) {
synchronized (this) {
if (mBackgroundStartPrivileges == null
|| mBackgroundStartPrivileges.isEmpty()) {
// no tokens to allow anything
- return false;
+ return BalVerdict.BLOCK;
}
if (isCheckingForFgsStart) {
// check if any token allows foreground service starts
for (int i = mBackgroundStartPrivileges.size(); i-- > 0; ) {
if (mBackgroundStartPrivileges.valueAt(i).allowsBackgroundFgsStarts()) {
- return true;
+ return new BalVerdict(BAL_ALLOW_TOKEN, "process allowed by token");
}
}
- return false;
+ return BalVerdict.BLOCK;
}
if (mBackgroundActivityStartCallback == null) {
// without a callback just check if any token allows background activity starts
for (int i = mBackgroundStartPrivileges.size(); i-- > 0; ) {
if (mBackgroundStartPrivileges.valueAt(i)
.allowsBackgroundActivityStarts()) {
- return true;
+ return new BalVerdict(BAL_ALLOW_TOKEN, "process allowed by token");
}
}
- return false;
+ return BalVerdict.BLOCK;
}
List<IBinder> binderTokens = getOriginatingTokensThatAllowBal();
if (binderTokens.isEmpty()) {
// no tokens to allow anything
- return false;
+ return BalVerdict.BLOCK;
}
// The callback will decide.
- return mBackgroundActivityStartCallback.isActivityStartAllowed(
+ BackgroundActivityStartCallback.BackgroundActivityStartCallbackResult
+ activityStartAllowed = mBackgroundActivityStartCallback.isActivityStartAllowed(
binderTokens, uid, packageName);
+ if (!activityStartAllowed.allowed()) {
+ return BalVerdict.BLOCK;
+ }
+ if (activityStartAllowed.token() == null) {
+ return new BalVerdict(BAL_ALLOW_TOKEN,
+ "process allowed by callback (token ignored) tokens: " + binderTokens);
+ }
+ return new BalVerdict(BAL_ALLOW_TOKEN,
+ "process allowed by callback (token: " + activityStartAllowed.token()
+ + ") tokens: " + binderTokens);
}
}
diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
index fee5566af484..d8087265c1d3 100644
--- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
+++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
@@ -69,11 +69,11 @@ public class DesktopAppCompatAspectRatioPolicy {
* Calculates the final aspect ratio of an launching activity based on the task it will be
* launched in. Takes into account any min or max aspect ratio constraints.
*/
- float calculateAspectRatio(@NonNull Task task) {
+ float calculateAspectRatio(@NonNull Task task, boolean hasOrientationMismatch) {
final float maxAspectRatio = getMaxAspectRatio();
final float minAspectRatio = getMinAspectRatio(task);
float desiredAspectRatio = 0;
- desiredAspectRatio = getDesiredAspectRatio(task);
+ desiredAspectRatio = getDesiredAspectRatio(task, hasOrientationMismatch);
if (maxAspectRatio >= 1 && desiredAspectRatio > maxAspectRatio) {
desiredAspectRatio = maxAspectRatio;
} else if (minAspectRatio >= 1 && desiredAspectRatio < minAspectRatio) {
@@ -87,13 +87,14 @@ public class DesktopAppCompatAspectRatioPolicy {
* any min or max aspect ratio constraints.
*/
@VisibleForTesting
- float getDesiredAspectRatio(@NonNull Task task) {
+ float getDesiredAspectRatio(@NonNull Task task, boolean hasOrientationMismatch) {
final float letterboxAspectRatioOverride = getFixedOrientationLetterboxAspectRatio(task);
// Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will
// be respected in #calculateAspectRatio.
if (isDefaultMultiWindowLetterboxAspectRatioDesired(task)) {
return DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
- } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
+ } else if (hasOrientationMismatch
+ && letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
return letterboxAspectRatioOverride;
}
return AppCompatUtils.computeAspectRatio(task.getDisplayArea().getBounds());
diff --git a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
index d9354323ae7c..83ca5f6f83f4 100644
--- a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
+++ b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.isFixedOrientation;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
@@ -32,8 +31,8 @@ import static com.android.server.wm.LaunchParamsUtil.calculateLayoutBounds;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.ActivityInfo.WindowLayout;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.util.Size;
@@ -152,19 +151,25 @@ public final class DesktopModeBoundsCalculator {
}
final DesktopAppCompatAspectRatioPolicy desktopAppCompatAspectRatioPolicy =
activity.mAppCompatController.getDesktopAspectRatioPolicy();
- float appAspectRatio = desktopAppCompatAspectRatioPolicy.calculateAspectRatio(task);
+ final int stableBoundsOrientation = stableBounds.height() >= stableBounds.width()
+ ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
+ int activityOrientation = getActivityConfigurationOrientation(
+ activity, task, stableBoundsOrientation);
+ // Use orientation mismatch to resolve aspect ratio to match fixed orientation letterboxing
+ // policy in {@link ActivityRecord.resolveFixedOrientationConfiguration}
+ final boolean hasOrientationMismatch = stableBoundsOrientation != activityOrientation;
+ float appAspectRatio = desktopAppCompatAspectRatioPolicy.calculateAspectRatio(
+ task, hasOrientationMismatch);
final float tdaWidth = stableBounds.width();
final float tdaHeight = stableBounds.height();
- final int taskConfigOrientation = task.getConfiguration().orientation;
- final int activityOrientation = getActivityOrientation(activity, task);
- final Size initialSize = switch (taskConfigOrientation) {
+ final Size initialSize = switch (stableBoundsOrientation) {
case ORIENTATION_LANDSCAPE -> {
// Device in landscape orientation.
if (appAspectRatio == 0) {
appAspectRatio = 1;
}
if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) {
- if (isFixedOrientationPortrait(activityOrientation)) {
+ if (hasOrientationMismatch) {
// For portrait resizeable activities, respect apps fullscreen width but
// apply ideal size height.
yield new Size((int) ((tdaHeight / appAspectRatio) + 0.5f),
@@ -183,7 +188,7 @@ public final class DesktopModeBoundsCalculator {
final int customPortraitWidthForLandscapeApp = screenBounds.width()
- (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) {
- if (isFixedOrientationLandscape(activityOrientation)) {
+ if (hasOrientationMismatch) {
if (appAspectRatio == 0) {
appAspectRatio = tdaWidth / (tdaWidth - 1);
}
@@ -198,7 +203,7 @@ public final class DesktopModeBoundsCalculator {
if (appAspectRatio == 0) {
appAspectRatio = 1;
}
- if (isFixedOrientationLandscape(activityOrientation)) {
+ if (hasOrientationMismatch) {
// For landscape unresizeable activities, apply custom app width to ideal size
// and calculate maximum size with this area while maintaining original aspect
// ratio.
@@ -230,19 +235,23 @@ public final class DesktopModeBoundsCalculator {
&& !desktopAppCompatAspectRatioPolicy.hasMinAspectRatioOverride(task);
}
- private static @ScreenOrientation int getActivityOrientation(
- @NonNull ActivityRecord activity, @NonNull Task task) {
+ private static @Configuration.Orientation int getActivityConfigurationOrientation(
+ @NonNull ActivityRecord activity, @NonNull Task task,
+ @Configuration.Orientation int stableBoundsOrientation) {
final int activityOrientation = activity.getOverrideOrientation();
final DesktopAppCompatAspectRatioPolicy desktopAppCompatAspectRatioPolicy =
activity.mAppCompatController.getDesktopAspectRatioPolicy();
- if (desktopAppCompatAspectRatioPolicy.shouldApplyUserMinAspectRatioOverride(task)
+ if ((desktopAppCompatAspectRatioPolicy.shouldApplyUserMinAspectRatioOverride(task)
&& (!isFixedOrientation(activityOrientation)
- || activityOrientation == SCREEN_ORIENTATION_LOCKED)) {
+ || activityOrientation == SCREEN_ORIENTATION_LOCKED))
+ || isFixedOrientationPortrait(activityOrientation)) {
// If a user aspect ratio override should be applied, treat the activity as portrait if
// it has not specified a fix orientation.
- return SCREEN_ORIENTATION_PORTRAIT;
+ return ORIENTATION_PORTRAIT;
}
- return activityOrientation;
+ // If activity orientation is undefined inherit task orientation.
+ return isFixedOrientationLandscape(activityOrientation)
+ ? ORIENTATION_LANDSCAPE : stableBoundsOrientation;
}
/**
@@ -252,7 +261,7 @@ public final class DesktopModeBoundsCalculator {
// TODO(b/400617906): Merge duplicate initial bounds calculations to shared class.
@NonNull
private static Size maximizeSizeGivenAspectRatio(
- @ScreenOrientation int orientation,
+ @Configuration.Orientation int orientation,
@NonNull Size targetArea,
float aspectRatio,
int captionHeight
@@ -261,7 +270,7 @@ public final class DesktopModeBoundsCalculator {
final int targetWidth = targetArea.getWidth();
final int finalHeight;
final int finalWidth;
- if (isFixedOrientationPortrait(orientation)) {
+ if (orientation == ORIENTATION_PORTRAIT) {
// Portrait activity.
// Calculate required width given ideal height and aspect ratio.
int tempWidth = (int) (targetHeight / aspectRatio);
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index eafc8be7bf77..016cebac2b86 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -24,6 +24,10 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.hardware.HardwareBuffer;
+import android.media.Image;
+import android.media.ImageReader;
import android.os.Process;
import android.os.SystemClock;
import android.os.Trace;
@@ -33,10 +37,12 @@ import android.window.TaskSnapshot;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.TransitionAnimation;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto;
+import com.android.window.flags.Flags;
import java.io.File;
import java.io.FileOutputStream;
@@ -400,23 +406,20 @@ class SnapshotPersistQueue {
Slog.e(TAG, "Invalid task snapshot hw buffer, taskId=" + mId);
return false;
}
- final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
- mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
- if (bitmap == null) {
- Slog.e(TAG, "Invalid task snapshot hw bitmap");
- return false;
- }
- final Bitmap swBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false /* isMutable */);
+ final HardwareBuffer hwBuffer = mSnapshot.getHardwareBuffer();
+ final int width = hwBuffer.getWidth();
+ final int height = hwBuffer.getHeight();
+ final int pixelFormat = hwBuffer.getFormat();
+ final Bitmap swBitmap = !Flags.reduceTaskSnapshotMemoryUsage()
+ || (pixelFormat != PixelFormat.RGB_565 && pixelFormat != PixelFormat.RGBA_8888)
+ || !mSnapshot.isRealSnapshot()
+ || TransitionAnimation.hasProtectedContent(hwBuffer)
+ ? copyToSwBitmapReadBack()
+ : copyToSwBitmapDirect(width, height, pixelFormat);
if (swBitmap == null) {
- Slog.e(TAG, "Bitmap conversion from (config=" + bitmap.getConfig() + ", isMutable="
- + bitmap.isMutable() + ") to (config=ARGB_8888, isMutable=false) failed.");
return false;
}
- final int width = bitmap.getWidth();
- final int height = bitmap.getHeight();
- bitmap.recycle();
-
final File file = mPersistInfoProvider.getHighResolutionBitmapFile(mId, mUserId);
try (FileOutputStream fos = new FileOutputStream(file)) {
swBitmap.compress(JPEG, COMPRESS_QUALITY, fos);
@@ -448,6 +451,58 @@ class SnapshotPersistQueue {
return true;
}
+ private Bitmap copyToSwBitmapReadBack() {
+ final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
+ mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
+ if (bitmap == null) {
+ Slog.e(TAG, "Invalid task snapshot hw bitmap");
+ return null;
+ }
+
+ final Bitmap swBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false /* isMutable */);
+ if (swBitmap == null) {
+ Slog.e(TAG, "Bitmap conversion from (config=" + bitmap.getConfig()
+ + ", isMutable=" + bitmap.isMutable()
+ + ") to (config=ARGB_8888, isMutable=false) failed.");
+ return null;
+ }
+ bitmap.recycle();
+ return swBitmap;
+ }
+
+ /**
+ * Use ImageReader to create the software bitmap, so SkImage won't create an extra texture.
+ */
+ private Bitmap copyToSwBitmapDirect(int width, int height, int pixelFormat) {
+ try (ImageReader ir = ImageReader.newInstance(width, height,
+ pixelFormat, 1 /* maxImages */)) {
+ ir.getSurface().attachAndQueueBufferWithColorSpace(mSnapshot.getHardwareBuffer(),
+ mSnapshot.getColorSpace());
+ try (Image image = ir.acquireLatestImage()) {
+ if (image == null || image.getPlaneCount() < 1) {
+ Slog.e(TAG, "Image reader cannot acquire image");
+ return null;
+ }
+
+ final Image.Plane[] planes = image.getPlanes();
+ if (planes.length != 1) {
+ Slog.e(TAG, "Image reader cannot get plane");
+ return null;
+ }
+ final Image.Plane plane = planes[0];
+ final int rowPadding = plane.getRowStride() - plane.getPixelStride()
+ * image.getWidth();
+ final Bitmap swBitmap = Bitmap.createBitmap(
+ image.getWidth() + rowPadding / plane.getPixelStride() /* width */,
+ image.getHeight() /* height */,
+ pixelFormat == PixelFormat.RGB_565
+ ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888);
+ swBitmap.copyPixelsFromBuffer(plane.getBuffer());
+ return swBitmap;
+ }
+ }
+ }
+
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 8587b5a9c7ca..0531828be6d4 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1832,6 +1832,17 @@ class Task extends TaskFragment {
&& supportsMultiWindowInDisplayArea(tda);
}
+ /** Returns true if the task bounds should persist across power cycles. */
+ private static boolean persistTaskBounds(@NonNull WindowConfiguration configuration) {
+ return configuration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+ }
+
+ /** Returns true if the nested task is allowed to have independent bounds from its parent. */
+ private static boolean allowIndependentBoundsFromParent(
+ @NonNull WindowConfiguration configuration) {
+ return configuration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+ }
+
/**
* Check whether this task can be launched on the specified display.
*
@@ -1996,11 +2007,11 @@ class Task extends TaskFragment {
private void onConfigurationChangedInner(Configuration newParentConfig) {
// Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
// restore the last recorded non-fullscreen bounds.
- final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
- boolean nextPersistTaskBounds =
- getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds();
+ final boolean prevPersistTaskBounds = persistTaskBounds(getWindowConfiguration());
+ boolean nextPersistTaskBounds = persistTaskBounds(
+ getRequestedOverrideConfiguration().windowConfiguration);
if (getRequestedOverrideWindowingMode() == WINDOWING_MODE_UNDEFINED) {
- nextPersistTaskBounds = newParentConfig.windowConfiguration.persistTaskBounds();
+ nextPersistTaskBounds = persistTaskBounds(newParentConfig.windowConfiguration);
}
// Only restore to the last non-fullscreen bounds when the requested override bounds
// have not been explicitly set already.
@@ -2042,7 +2053,7 @@ class Task extends TaskFragment {
// If the configuration supports persistent bounds (eg. Freeform), keep track of the
// current (non-fullscreen) bounds for persistence.
- if (getWindowConfiguration().persistTaskBounds()) {
+ if (persistTaskBounds(getWindowConfiguration())) {
final Rect currentBounds = getRequestedOverrideBounds();
if (!currentBounds.isEmpty()) {
setLastNonFullscreenBounds(currentBounds);
@@ -2383,33 +2394,48 @@ class Task extends TaskFragment {
}
void updateOverrideConfigurationFromLaunchBounds() {
- // If the task is controlled by another organized task, do not set override
- // configurations and let its parent (organized task) to control it;
final Task rootTask = getRootTask();
- boolean shouldInheritBounds = rootTask != this && rootTask.isOrganized();
- if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
- // Only inherit from organized parent when this task is not organized.
- shouldInheritBounds &= !isOrganized();
+ final boolean hasParentTask = rootTask != this;
+ final int windowingMode = getWindowingMode();
+ final boolean isNonStandardOrFullscreen = !isActivityTypeStandardOrUndefined()
+ || windowingMode == WINDOWING_MODE_FULLSCREEN;
+ if (!Flags.nestedTasksWithIndependentBounds()
+ && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
+ final Rect bounds;
+ if (hasParentTask && rootTask.isOrganized()) {
+ bounds = null;
+ } else if (isNonStandardOrFullscreen) {
+ bounds = isResizeable() ? rootTask.getRequestedOverrideBounds() : null;
+ } else if (!persistTaskBounds(getWindowConfiguration())) {
+ bounds = rootTask.getRequestedOverrideBounds();
+ } else {
+ bounds = mLastNonFullscreenBounds;
+ }
+ setBounds(bounds);
+ return;
}
- final Rect bounds = shouldInheritBounds ? null : getLaunchBounds();
- setBounds(bounds);
- }
- /** Returns the bounds that should be used to launch this task. */
- Rect getLaunchBounds() {
- final Task rootTask = getRootTask();
- if (rootTask == null) {
- return null;
+ // Non-standard/fullscreen unresizable tasks should always inherit.
+ boolean shouldInheritBounds = isNonStandardOrFullscreen && !isResizeable();
+ // Task itself is not organized (e.g. Home), just inherit from its organized parent.
+ shouldInheritBounds |= hasParentTask && rootTask.isOrganized() && !isOrganized();
+ // Nested tasks should inherit when they're not allowed to have independent bounds, such as
+ // in multi-window split-screen.
+ shouldInheritBounds |= hasParentTask
+ && !(allowIndependentBoundsFromParent(getWindowConfiguration())
+ && persistTaskBounds(getWindowConfiguration()));
+ if (shouldInheritBounds) {
+ setBounds(null);
+ return;
}
-
- final int windowingMode = getWindowingMode();
- if (!isActivityTypeStandardOrUndefined()
- || windowingMode == WINDOWING_MODE_FULLSCREEN) {
- return isResizeable() ? rootTask.getRequestedOverrideBounds() : null;
- } else if (!getWindowConfiguration().persistTaskBounds()) {
- return rootTask.getRequestedOverrideBounds();
+ if (!hasParentTask && !persistTaskBounds(getWindowConfiguration())) {
+ // Non-nested, non-persistable tasks such as PIP or multi-window floating windows.
+ return;
}
- return mLastNonFullscreenBounds;
+ // Non-nested, persisted tasks (e.g. top-level freeform) or nested persisted tasks that
+ // allow independent bounds from parent (e.g. nested freeform) should use launch-params
+ // bounds set to |mLastNonFullscreenBounds|.
+ setBounds(mLastNonFullscreenBounds);
}
void setRootProcess(WindowProcessController proc) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 2c10af4c5851..65001f436d3f 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -3401,7 +3401,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
* Applies the new configuration for the changed displays. Returns the activities that should
* check whether to deliver the new configuration to clients.
*/
- @Nullable
void applyDisplayChangeIfNeeded(@NonNull ArraySet<WindowContainer<?>> activitiesMayChange) {
for (int i = mParticipants.size() - 1; i >= 0; --i) {
final WindowContainer<?> wc = mParticipants.valueAt(i);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 9b3b4451a746..51c3da098020 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -1284,13 +1284,14 @@ class TransitionController {
// ignore ourself obviously
if (mPlayingTransitions.get(i) == transition) continue;
if (getIsIndependent(mPlayingTransitions.get(i), transition)) continue;
- if (track >= 0) {
+ if (track < 0) {
+ track = mPlayingTransitions.get(i).mAnimationTrack;
+ } else if (track != mPlayingTransitions.get(i).mAnimationTrack) {
// At this point, transition overlaps with multiple tracks, so just wait for
// everything
sync = true;
break;
}
- track = mPlayingTransitions.get(i).mAnimationTrack;
}
if (sync) {
track = 0;
diff --git a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
index f6b107b60d62..d60807c7b001 100644
--- a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
@@ -62,6 +62,8 @@ public class PrepareGetRequestSession extends GetRequestSession {
Collectors.toSet())).size(); // Dedupe type strings
mRequestSessionMetric.collectGetFlowInitialMetricInfo(request);
mPrepareGetCredentialCallback = prepareGetCredentialCallback;
+
+ Slog.i(TAG, "PrepareGetRequestSession constructed.");
}
@Override
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 788b3b883160..56ec27a0ba87 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -121,6 +121,7 @@ import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockSettingsInternal;
+import com.android.modules.utils.build.SdkLevel;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accounts.AccountManagerService;
import com.android.server.adb.AdbService;
@@ -2265,19 +2266,27 @@ public final class SystemServer implements Dumpable {
Slog.i(TAG, "Not starting VpnManagerService");
}
- t.traceBegin("StartVcnManagementService");
- try {
- if (VcnLocation.IS_VCN_IN_MAINLINE) {
- mSystemServiceManager.startServiceFromJar(
- CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS,
- CONNECTIVITY_SERVICE_APEX_PATH);
- } else {
- mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+ // TODO: b/374174952 In the end state, VCN registration will be moved to Tethering
+ // module. Thus the following code block should be removed after Baklava is released
+ if (!VcnLocation.IS_VCN_IN_MAINLINE || !SdkLevel.isAtLeastB()) {
+ t.traceBegin("StartVcnManagementService");
+
+ try {
+ if (!VcnLocation.IS_VCN_IN_MAINLINE) {
+ mSystemServiceManager.startService(
+ CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+ } else {
+ // When VCN is in mainline but the SDK level is B-, start the service with
+ // the apex path. This path can only be hit on an unfinalized B platform
+ mSystemServiceManager.startServiceFromJar(
+ CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS,
+ CONNECTIVITY_SERVICE_APEX_PATH);
+ }
+ } catch (Throwable e) {
+ reportWtf("starting VCN Management Service", e);
}
- } catch (Throwable e) {
- reportWtf("starting VCN Management Service", e);
+ t.traceEnd();
}
- t.traceEnd();
t.traceBegin("StartSystemUpdateManagerService");
try {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
index 987b9c6427d8..3289d70b89ac 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
@@ -680,6 +680,67 @@ public class ApplicationStartInfoTest {
ApplicationStartInfo.START_TIMESTAMP_FORK));
}
+ /**
+ * Test that cleanup old records works as expected, removing records that are older than the max
+ * retention length.
+ */
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_APP_START_INFO_CLEANUP_OLD_RECORDS)
+ public void testOldRecordsCleanup() throws Exception {
+ // Use a different start timestamp for each record so we can identify which was removed.
+ // This timestamp is not used for ordering and has no impact on removal.
+ final long startTimeRecord1 = 123L;
+ final long startTimeRecord2 = 456L;
+ final long startTimeRecord3 = 789L;
+
+ // Create a process record to use with all starts.
+ ProcessRecord app = makeProcessRecord(
+ APP_1_PID_1, // pid
+ APP_1_UID, // uid
+ APP_1_UID, // packageUid
+ null, // definingUid
+ APP_1_PROCESS_NAME, // processName
+ APP_1_PACKAGE_NAME); // packageName
+
+ // Set monotonic time to 1, and then trigger a start info record.
+ doReturn(1L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+ mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord1, app,
+ buildIntent(COMPONENT), false /* isAlarm */);
+
+ // Set monotonic time to 2, and then trigger another start info record.
+ doReturn(2L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+ mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord2, app,
+ buildIntent(COMPONENT), false /* isAlarm */);
+
+ // Set monotonic time to 3, then trigger another start info record.
+ doReturn(3L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+ mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord3, app,
+ buildIntent(COMPONENT), false /* isAlarm */);
+
+ // Verify that all 3 records were added successfully.
+ ArrayList<ApplicationStartInfo> list = new ArrayList<ApplicationStartInfo>();
+ mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+ assertEquals(3, list.size());
+ assertEquals(startTimeRecord3, list.get(0).getStartupTimestamps().get(0).longValue());
+ assertEquals(startTimeRecord2, list.get(1).getStartupTimestamps().get(0).longValue());
+ assertEquals(startTimeRecord1, list.get(2).getStartupTimestamps().get(0).longValue());
+
+ // Set monotonic time to max history length + 3 so that the older 2 records will be removed
+ // but that newest 1 will remain.
+ doReturn(AppStartInfoTracker.APP_START_INFO_HISTORY_LENGTH_MS + 3L)
+ .when(mAppStartInfoTracker).getMonotonicTimeMs();
+
+ // Trigger a persist which will trigger the cleanup of old records.
+ mAppStartInfoTracker.persistProcessStartInfo();
+
+ // Now verify that the records older than max were removed, and that the records not older
+ // remain.
+ list.clear();
+ mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+ assertEquals(1, list.size());
+ assertEquals(startTimeRecord3, list.get(0).getStartupTimestamps().get(0).longValue());
+ }
+
private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) {
try {
Field field = clazz.getDeclaredField(fieldName);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
index 43becc59c3cb..558ea29d85fc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ProcessObserverTest.java
@@ -42,6 +42,8 @@ import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Log;
import androidx.test.filters.MediumTest;
@@ -79,6 +81,8 @@ public class ProcessObserverTest {
@Rule
public final ApplicationExitInfoTest.ServiceThreadRule
mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private HandlerThread mHandlerThread;
@@ -239,8 +243,8 @@ public class ProcessObserverTest {
/**
* Verify that a process start event is dispatched to process observers.
*/
- @Ignore("b/323959187")
@Test
+ @EnableFlags(android.app.Flags.FLAG_ENABLE_PROCESS_OBSERVER_BROADCAST_ON_PROCESS_STARTED)
public void testNormal() throws Exception {
ProcessRecord app = startProcess();
verify(mProcessObserver).onProcessStarted(
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 8c09f26bb7fa..fdf78ad88311 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -56,12 +56,12 @@ import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.UiModeManager;
+import android.app.compat.CompatChanges;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobWorkItem;
import android.app.usage.UsageStatsManagerInternal;
-import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -81,6 +81,7 @@ import android.os.BatteryManagerInternal.ChargingPolicyChangeListener;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
@@ -98,6 +99,7 @@ import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
import com.android.server.SystemServiceManager;
+import com.android.server.compat.PlatformCompat;
import com.android.server.job.controllers.ConnectivityController;
import com.android.server.job.controllers.JobStatus;
import com.android.server.job.controllers.QuotaController;
@@ -106,14 +108,10 @@ import com.android.server.job.restrictions.ThermalStatusRestriction;
import com.android.server.pm.UserManagerInternal;
import com.android.server.usage.AppStandbyInternal;
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestRule;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
@@ -147,9 +145,6 @@ public class JobSchedulerServiceTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
- @Rule
- public TestRule compatChangeRule = new PlatformCompatChangeRule();
-
private ChargingPolicyChangeListener mChargingPolicyChangeListener;
private int mSourceUid;
@@ -166,8 +161,10 @@ public class JobSchedulerServiceTest {
mMockingSession = mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
+ .mockStatic(CompatChanges.class)
.mockStatic(LocalServices.class)
.mockStatic(PermissionChecker.class)
+ .mockStatic(ServiceManager.class)
.startMocking();
// Called in JobSchedulerService constructor.
@@ -230,6 +227,9 @@ public class JobSchedulerServiceTest {
ArgumentCaptor<ChargingPolicyChangeListener> chargingPolicyChangeListenerCaptor =
ArgumentCaptor.forClass(ChargingPolicyChangeListener.class);
+ doReturn(mock(PlatformCompat.class))
+ .when(() -> ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
mService = new TestJobSchedulerService(mContext);
mService.waitOnAsyncLoadingForTesting();
@@ -1074,12 +1074,15 @@ public class JobSchedulerServiceTest {
*/
@Test
@EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
- @DisableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
public void testGetRescheduleJobForFailure_abandonedJob() {
final long nowElapsed = sElapsedRealtimeClock.millis();
final long initialBackoffMs = MINUTE_IN_MILLIS;
mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO = 3;
+ // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+ when(CompatChanges.isChangeEnabled(
+ eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(false);
+
JobStatus originalJob = createJobStatus("testGetRescheduleJobForFailure",
createJobInfo()
.setBackoffCriteria(initialBackoffMs, JobInfo.BACKOFF_POLICY_LINEAR));
@@ -1148,8 +1151,10 @@ public class JobSchedulerServiceTest {
*/
@Test
@EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
- @DisableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
public void testGetRescheduleJobForFailure_EnableFlagDisableCompatCheckAggressiveBackoff() {
+ // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+ when(CompatChanges.isChangeEnabled(
+ eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(false);
assertFalse(mService.shouldUseAggressiveBackoff(
mService.mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF - 1,
mSourceUid));
@@ -1167,8 +1172,10 @@ public class JobSchedulerServiceTest {
*/
@Test
@EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
- @EnableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
public void testGetRescheduleJobForFailure_EnableFlagEnableCompatCheckAggressiveBackoff() {
+ // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+ when(CompatChanges.isChangeEnabled(
+ eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(true);
assertFalse(mService.shouldUseAggressiveBackoff(
mService.mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF - 1,
mSourceUid));
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 2d84887afb41..924fe9586af9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -76,6 +76,7 @@ import android.os.BatteryManagerInternal;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -93,6 +94,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
+import com.android.server.compat.PlatformCompat;
import com.android.server.job.Flags;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.job.JobSchedulerService;
@@ -104,8 +106,6 @@ import com.android.server.job.controllers.QuotaController.TimedEvent;
import com.android.server.job.controllers.QuotaController.TimingSession;
import com.android.server.usage.AppStandbyInternal;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -168,6 +168,8 @@ public class QuotaControllerTest {
private PowerAllowlistInternal mPowerAllowlistInternal;
@Mock
private UsageStatsManagerInternal mUsageStatsManager;
+ @Mock
+ private PlatformCompat mPlatformCompat;
@Rule
public final CheckFlagsRule mCheckFlagsRule =
@@ -182,6 +184,7 @@ public class QuotaControllerTest {
.strictness(Strictness.LENIENT)
.spyStatic(DeviceConfig.class)
.mockStatic(LocalServices.class)
+ .mockStatic(ServiceManager.class)
.startMocking();
// Called in StateController constructor.
@@ -198,6 +201,7 @@ public class QuotaControllerTest {
}
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager);
+
doReturn(mActivityMangerInternal)
.when(() -> LocalServices.getService(ActivityManagerInternal.class));
doReturn(mock(AppStandbyInternal.class))
@@ -253,6 +257,8 @@ public class QuotaControllerTest {
ArgumentCaptor.forClass(PowerAllowlistInternal.TempAllowlistChangeListener.class);
ArgumentCaptor<UsageStatsManagerInternal.UsageEventListener> ueListenerCaptor =
ArgumentCaptor.forClass(UsageStatsManagerInternal.UsageEventListener.class);
+ doReturn(mPlatformCompat)
+ .when(() -> ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
mQuotaController = new QuotaController(mJobSchedulerService,
mock(BackgroundJobsController.class), mock(ConnectivityController.class));
@@ -5591,13 +5597,17 @@ public class QuotaControllerTest {
}
@Test
- @EnableCompatChanges({QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
- QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS})
@RequiresFlagsEnabled({Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_TOP_STARTED_JOBS,
Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_FGS_JOBS})
public void testTracking_OutOfQuota_ForegroundAndBackground_CompactChangeOverrides() {
setDischarging();
+ // Mock the OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS compat change overrides.
+ doReturn(true).when(mPlatformCompat).isChangeEnabledByUid(
+ eq(QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS), anyInt());
+ doReturn(true).when(mPlatformCompat).isChangeEnabledByUid(
+ eq(QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS), anyInt());
+
JobStatus jobBg = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 1);
JobStatus jobTop = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 2);
trackJobs(jobBg, jobTop);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index fc864dd230d9..3ed4a52bed23 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -343,12 +343,13 @@ public class BatteryStatsHistoryTest {
assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
} else if (item.eventCode == HistoryItem.EVENT_ALARM) {
eventsRead++;
- assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh");
+ // This event is in the current buffer, so 2000.bh shouldn't be read from disk
+ assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
}
}
assertThat(eventsRead).isEqualTo(3);
- assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh", "3000.bh");
+ assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
}
@Test
@@ -366,34 +367,41 @@ public class BatteryStatsHistoryTest {
return invocation.callRealMethod();
}).when(mHistory).readFragmentToParcel(any(), any());
- BatteryStatsHistoryIterator iterator = mHistory.iterate(1000, 3000);
+ int eventsRead = 0;
+ BatteryStatsHistoryIterator iterator = mHistory.iterate(1001, 3000);
while (iterator.hasNext()) {
HistoryItem item = iterator.next();
if (item.eventCode == HistoryItem.EVENT_JOB_START) {
fail("Event outside the range");
} else if (item.eventCode == HistoryItem.EVENT_JOB_FINISH) {
+ eventsRead++;
assertThat(mReadFiles).containsExactly("1000.bh");
} else if (item.eventCode == HistoryItem.EVENT_ALARM) {
fail("Event outside the range");
}
}
- assertThat(mReadFiles).containsExactly("1000.bh", "2000.bh");
+ assertThat(eventsRead).isEqualTo(1);
+ assertThat(mReadFiles).containsExactly("1000.bh");
}
private void prepareMultiFileHistory() {
- mClock.realtime = 1000;
- mClock.uptime = 1000;
+ mClock.realtime = 500;
+ mClock.uptime = 500;
mHistory.recordEvent(mClock.realtime, mClock.uptime,
BatteryStats.HistoryItem.EVENT_JOB_START, "job", 42);
+ mClock.realtime = 1000;
+ mClock.uptime = 1000;
mHistory.startNextFragment(mClock.realtime); // 1000.bh
- mClock.realtime = 2000;
- mClock.uptime = 2000;
+ mClock.realtime = 1500;
+ mClock.uptime = 1500;
mHistory.recordEvent(mClock.realtime, mClock.uptime,
BatteryStats.HistoryItem.EVENT_JOB_FINISH, "job", 42);
+ mClock.realtime = 2000;
+ mClock.uptime = 2000;
mHistory.startNextFragment(mClock.realtime); // 2000.bh
mClock.realtime = 3000;
@@ -401,8 +409,8 @@ public class BatteryStatsHistoryTest {
mHistory.recordEvent(mClock.realtime, mClock.uptime,
HistoryItem.EVENT_ALARM, "alarm", 42);
- // Flush accumulated history to disk
- mHistory.startNextFragment(mClock.realtime);
+ // Back up accumulated history to disk
+ mHistory.writeHistory();
}
private void verifyActiveFile(BatteryStatsHistory history, String file) {
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 2ccd33648c3e..e0bc3e76f31d 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -82,6 +82,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Icon;
import android.hardware.display.DisplayManager;
@@ -131,6 +132,7 @@ import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.content.PackageMonitor;
import com.android.server.LocalServices;
+import com.android.server.SystemService;
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.MagnificationConnectionManager;
@@ -2122,6 +2124,36 @@ public class AccessibilityManagerServiceTest {
}
@Test
+ @EnableFlags(Flags.FLAG_MANAGER_LIFECYCLE_USER_CHANGE)
+ public void lifecycle_onUserSwitching_switchesUser() throws RemoteException {
+ mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback);
+ AccessibilityManagerService.Lifecycle lifecycle =
+ new AccessibilityManagerService.Lifecycle(mTestableContext, mA11yms);
+ int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
+
+ lifecycle.onUserSwitching(
+ new SystemService.TargetUser(new UserInfo(0, "USER", 0)),
+ new SystemService.TargetUser(new UserInfo(newUserId, "USER", 0)));
+ mTestableLooper.processAllMessages();
+
+ verify(mUserInitializationCompleteCallback).onUserInitializationComplete(newUserId);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_MANAGER_LIFECYCLE_USER_CHANGE)
+ public void intent_user_switched_switchesUser() throws RemoteException {
+ mA11yms.mUserInitializationCompleteCallbacks.add(mUserInitializationCompleteCallback);
+ int newUserId = mA11yms.getCurrentUserIdLocked() + 1;
+ final Intent intent = new Intent(Intent.ACTION_USER_SWITCHED);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
+
+ sendBroadcastToAccessibilityManagerService(intent, mA11yms.getCurrentUserIdLocked());
+ mTestableLooper.processAllMessages();
+
+ verify(mUserInitializationCompleteCallback).onUserInitializationComplete(newUserId);
+ }
+
+ @Test
@DisableFlags(android.provider.Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
public void getShortcutTypeForGenericShortcutCalls_softwareType() {
final AccessibilityUserState userState = new AccessibilityUserState(
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
index 3565244d90b3..33529c3f4375 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -207,6 +208,23 @@ public class HearingDevicePhoneCallNotificationControllerTest {
eq(SystemMessageProto.SystemMessage.NOTE_HEARING_DEVICE_INPUT_SWITCH), any());
}
+ @Test
+ @EnableFlags(Flags.FLAG_HEARING_INPUT_CHANGE_WHEN_COMM_DEVICE)
+ public void onCallStateChanged_offHookMultiple_addListenerOnlyOneTime() {
+ AudioDeviceInfo a2dpDeviceInfo = createAudioDeviceInfo(TEST_ADDRESS,
+ AudioManager.DEVICE_OUT_BLUETOOTH_A2DP);
+ when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+ new AudioDeviceInfo[]{a2dpDeviceInfo});
+ when(mAudioManager.getCommunicationDevice()).thenReturn(a2dpDeviceInfo);
+
+ mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+ mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+
+ verify(mAudioManager, times(1)).addOnCommunicationDeviceChangedListener(
+ any(Executor.class),
+ any(AudioManager.OnCommunicationDeviceChangedListener.class));
+ }
+
private AudioDeviceInfo createAudioDeviceInfo(String address, int type) {
AudioDevicePort audioDevicePort = mock(AudioDevicePort.class);
doReturn(type).when(audioDevicePort).type();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
index b2d48a77386f..2349120f8e76 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
@@ -226,13 +226,16 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
*/
protected void adoptFullVolumeBehaviorOnAvbCapableAudioOutputDevices() {
if (getDeviceType() == HdmiDeviceInfo.DEVICE_PLAYBACK) {
- mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+ HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
} else if (getDeviceType() == HdmiDeviceInfo.DEVICE_TV) {
- mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
- mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_EARC,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+ HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+ HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_EARC,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
}
@@ -307,8 +310,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute());
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
protected void enableAdjustOnlyAbsoluteVolumeBehavior() {
@@ -320,8 +324,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute());
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
}
protected void verifyGiveAudioStatusNeverSent() {
@@ -419,14 +424,16 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
// AVB should not be enabled before receiving <Report Audio Status>
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
receiveReportAudioStatus(60, false);
// Check that absolute volume behavior was the last one adopted
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
// Check that the volume and mute status received were included when setting AVB
verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeBehavior(
@@ -447,19 +454,22 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
enableSystemAudioModeIfNeeded();
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
receiveReportAudioStatus(127, false);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
public void avbEnabled_standby_avbDisabled() {
enableAbsoluteVolumeBehavior();
mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
@@ -468,8 +478,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_DISABLED);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
@@ -477,8 +488,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
enableAbsoluteVolumeBehavior();
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
@@ -489,8 +501,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
getSystemAudioDeviceLogicalAddress(), getLogicalAddress(),
Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL, Constants.ABORT_UNRECOGNIZED_OPCODE));
mTestLooper.dispatchAll();
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
@@ -501,8 +514,9 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
enableAbsoluteVolumeBehavior();
receiveSetSystemAudioMode(false);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
index 4c12e436542b..7c7e2207c59c 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
@@ -20,7 +20,7 @@ import android.hardware.hdmi.DeviceFeatures;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.AudioDeviceAttributes;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
import org.junit.Test;
@@ -60,8 +60,8 @@ public abstract class BasePlaybackDeviceAvbTest extends BaseAbsoluteVolumeBehavi
*/
@Test
public void savlNotSupported_allOtherConditionsMet_giveAudioStatusNotSent() {
- mAudioManager.setDeviceVolumeBehavior(getAudioOutputDevice(),
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ mAudioDeviceVolumeManager.setDeviceVolumeBehavior(getAudioOutputDevice(),
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
enableSystemAudioModeIfNeeded();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
index f44517a47f55..7a4359889994 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
@@ -96,13 +96,15 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
// Adjust-only AVB should not be enabled before receiving <Report Audio Status>
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
receiveReportAudioStatus(20, false);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
eq(getAudioOutputDevice()),
@@ -124,8 +126,9 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav
receiveReportAudioStatus(40, true);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
eq(getAudioOutputDevice()),
@@ -149,8 +152,9 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav
receiveReportAudioStatus(40, true);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
eq(getAudioOutputDevice()),
@@ -283,13 +287,15 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav
verifyGiveAudioStatusSent();
// The device should use adjust-only AVB while waiting for <Report Audio Status>
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
// The device should switch to AVB upon receiving <Report Audio Status>
receiveReportAudioStatus(60, false);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
@@ -321,8 +327,9 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav
mTestLooper.dispatchAll();
// The device should not switch away from adjust-only AVB
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
// The device should query support for <Set Audio Volume Level> again
assertThat(mNativeWrapper.getResultMessages()).contains(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
index 90f94cb4b596..e07f4f92084e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
@@ -23,6 +23,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.VolumeInfo;
@@ -137,18 +138,6 @@ public class FakeAudioFramework {
// Do nothing
}
-
- @Override
- @AudioManager.DeviceVolumeBehavior
- public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
- return mDeviceVolumeBehaviors.getOrDefault(device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
- }
-
- public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
- setVolumeBehaviorHelper(device, deviceVolumeBehavior);
- }
-
@Override
@NonNull
public List<AudioDeviceAttributes> getDevicesForAttributes(
@@ -186,7 +175,8 @@ public class FakeAudioFramework {
boolean handlesVolumeAdjustment,
@NonNull @CallbackExecutor Executor executor,
@NonNull OnAudioDeviceVolumeChangedListener vclistener) {
- setVolumeBehaviorHelper(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ setVolumeBehaviorHelper(device,
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
@Override
@@ -197,7 +187,19 @@ public class FakeAudioFramework {
@NonNull @CallbackExecutor Executor executor,
@NonNull OnAudioDeviceVolumeChangedListener vclistener) {
setVolumeBehaviorHelper(device,
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+ }
+
+ @Override
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior
+ public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
+ return mDeviceVolumeBehaviors.getOrDefault(device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
+ }
+
+ @Override
+ public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+ setVolumeBehaviorHelper(device, deviceVolumeBehavior);
}
}
@@ -222,7 +224,7 @@ public class FakeAudioFramework {
* Helper method for changing an audio device's volume behavior. Notifies listeners.
*/
private void setVolumeBehaviorHelper(AudioDeviceAttributes device,
- @AudioManager.DeviceVolumeBehavior int newVolumeBehavior) {
+ @AudioDeviceVolumeManager.DeviceVolumeBehavior int newVolumeBehavior) {
int currentVolumeBehavior = mDeviceVolumeBehaviors.getOrDefault(
device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
index 43ab804e04be..ffc1c62f79b3 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
@@ -21,7 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.hardware.hdmi.DeviceFeatures;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -64,8 +64,9 @@ public class PlaybackDeviceToAudioSystemAvbTest extends BasePlaybackDeviceAvbTes
// Audio System disables System Audio Mode. AVB should be disabled.
receiveSetSystemAudioMode(false);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
// TV reports support for <Set Audio Volume Level>
mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
@@ -85,7 +86,8 @@ public class PlaybackDeviceToAudioSystemAvbTest extends BasePlaybackDeviceAvbTes
false));
mTestLooper.dispatchAll();
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
index 9b343e34706a..092618072744 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.clearInvocations;
import android.hardware.hdmi.DeviceFeatures;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -65,8 +65,9 @@ public class PlaybackDeviceToTvAvbTest extends BasePlaybackDeviceAvbTest {
// Audio System enables System Audio Mode. AVB should be disabled.
receiveSetSystemAudioMode(true);
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
clearInvocations(mAudioManager, mAudioDeviceVolumeManager);
@@ -88,7 +89,8 @@ public class PlaybackDeviceToTvAvbTest extends BasePlaybackDeviceAvbTest {
false));
mTestLooper.dispatchAll();
- assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
- AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+ getAudioOutputDevice())).isEqualTo(
+ AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 125791acc61a..f312a1bdb985 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -17,7 +17,7 @@
package com.android.server.locksettings;
import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION;
-import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL;
+import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
@@ -264,7 +264,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_forPrimaryUser_clearsStrongAuthWhenFlagIsOn()
throws Exception {
setCredential(PRIMARY_USER_ID, newPassword("password"));
@@ -273,7 +273,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_forPrimaryUser_leavesStrongAuthWhenFlagIsOff()
throws Exception {
setCredential(PRIMARY_USER_ID, newPassword("password"));
@@ -312,7 +312,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_profileWithNewSeparateChallenge_clearsStrongAuthWhenFlagIsOn()
throws Exception {
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
@@ -323,7 +323,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_profileWithNewSeparateChallenge_leavesStrongAuthWhenFlagIsOff()
throws Exception {
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
@@ -377,7 +377,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_primaryWithUnifiedProfile_clearsStrongAuthForBothWhenFlagIsOn()
throws Exception {
final LockscreenCredential credential = newPassword("oldPassword");
@@ -393,7 +393,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
}
@Test
- @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+ @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
public void setLockCredential_primaryWithUnifiedProfile_leavesStrongAuthForBothWhenFlagIsOff()
throws Exception {
final LockscreenCredential credential = newPassword("oldPassword");
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index d1b2e8e6d868..1fb84113e278 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -274,7 +274,7 @@ public class UserManagerServiceUserInfoTest {
/** Test UserInfo.canHaveProfile for main user */
@Test
public void testCanHaveProfile() throws Exception {
- UserInfo userInfo = createUser(100, FLAG_MAIN, null);
+ UserInfo userInfo = createUser(100, FLAG_FULL | FLAG_MAIN, null);
assertTrue("Main users can have profile", userInfo.canHaveProfile());
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
index 036e03c60091..e473a06b25e7 100644
--- a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
@@ -49,6 +49,7 @@ public class CombinationKeyTests extends ShortcutKeyTestBase {
@Before
public void setUp() {
setUpPhoneWindowManager();
+ mPhoneWindowManager.overrideStatusBarManagerInternal();
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
index 27e147d98b1f..747b09cb5660 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java
@@ -74,14 +74,14 @@ public class BackgroundLaunchProcessControllerTests {
BackgroundActivityStartCallback mCallback = new BackgroundActivityStartCallback() {
@Override
- public boolean isActivityStartAllowed(Collection<IBinder> tokens, int uid,
- String packageName) {
+ public BackgroundActivityStartCallbackResult isActivityStartAllowed(
+ Collection<IBinder> tokens, int uid, String packageName) {
for (IBinder token : tokens) {
if (token == null || mActivityStartAllowed.contains(token)) {
- return true;
+ return new BackgroundActivityStartCallbackResult(true, token);
}
}
- return false;
+ return RESULT_FALSE;
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
index fa7dcc8ebbc7..81d753b8e079 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
@@ -35,6 +35,7 @@ import static com.android.server.wm.AppCompatConfiguration.DEFAULT_LETTERBOX_ASP
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.pm.ActivityInfo;
@@ -413,7 +414,7 @@ public class DesktopAppCompatAspectRatioPolicyTests extends WindowTestsBase {
void setDesiredAspectRatio(float aspectRatio) {
doReturn(aspectRatio).when(getDesktopAppCompatAspectRatioPolicy())
- .getDesiredAspectRatio(any());
+ .getDesiredAspectRatio(any(), anyBoolean());
}
DesktopAppCompatAspectRatioPolicy getDesktopAppCompatAspectRatioPolicy() {
@@ -422,7 +423,7 @@ public class DesktopAppCompatAspectRatioPolicyTests extends WindowTestsBase {
float calculateAspectRatio() {
return getDesktopAppCompatAspectRatioPolicy().calculateAspectRatio(
- getTopActivity().getTask());
+ getTopActivity().getTask(), /* hasOrientationMismatch */ true);
}
ActivityRecord getTopActivity() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
index 00b617e91bfd..f587d6e8c346 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
@@ -52,6 +52,7 @@ import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -437,7 +438,7 @@ public class DesktopModeLaunchParamsModifierTests extends
spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
- .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+ .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
final int desiredWidth =
(int) ((LANDSCAPE_DISPLAY_BOUNDS.height() / LETTERBOX_ASPECT_RATIO) + 0.5f);
@@ -933,7 +934,7 @@ public class DesktopModeLaunchParamsModifierTests extends
spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
- .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+ .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
final int desiredHeight =
(int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
@@ -1060,7 +1061,7 @@ public class DesktopModeLaunchParamsModifierTests extends
spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
- .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+ .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
final int desiredWidth = PORTRAIT_DISPLAY_BOUNDS.width()
- (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
@@ -1115,7 +1116,7 @@ public class DesktopModeLaunchParamsModifierTests extends
spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
- .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+ .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
final int desiredWidth = PORTRAIT_DISPLAY_BOUNDS.width()
- (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
@@ -1569,7 +1570,7 @@ public class DesktopModeLaunchParamsModifierTests extends
activity.mAppCompatController.getDesktopAspectRatioPolicy();
spyOn(desktopAppCompatAspectRatioPolicy);
doReturn(aspectRatio).when(desktopAppCompatAspectRatioPolicy)
- .getDesiredAspectRatio(any());
+ .getDesiredAspectRatio(any(), anyBoolean());
}
private void applyUserMinAspectRatioOverride(ActivityRecord activity, int overrideCode,
@@ -1579,7 +1580,7 @@ public class DesktopModeLaunchParamsModifierTests extends
activity.mAppCompatController.getDesktopAspectRatioPolicy();
spyOn(desktopAppCompatAspectRatioPolicy);
doReturn(1f).when(desktopAppCompatAspectRatioPolicy)
- .getDesiredAspectRatio(any());
+ .getDesiredAspectRatio(any(), anyBoolean());
// Enable user aspect ratio settings
final AppCompatConfiguration appCompatConfiguration =
diff --git a/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
index c52be7c2b0c6..8e012598c9eb 100644
--- a/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
+++ b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
@@ -21,7 +21,10 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import android.content.Context;
+import android.os.Bundle;
import android.security.FileIntegrityManager;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
@@ -35,8 +38,9 @@ import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
-import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
/**
* Test helper that works with the host-side test to set up a test file, and to verify fs-verity
@@ -47,8 +51,6 @@ public class Helper {
private static final String FILENAME = "test.file";
- private static final long BLOCK_SIZE = 4096;
-
@Rule
public final AdoptShellPermissionsRule mAdoptShellPermissionsRule =
new AdoptShellPermissionsRule(
@@ -58,7 +60,7 @@ public class Helper {
@Test
public void prepareTest() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
- android.os.Bundle testArgs = InstrumentationRegistry.getArguments();
+ Bundle testArgs = InstrumentationRegistry.getArguments();
String basename = testArgs.getString("basename");
context.deleteFile(basename);
@@ -84,31 +86,52 @@ public class Helper {
fim.setupFsVerity(context.getFileStreamPath(basename));
}
+ private static long getPageSize() {
+ String arch = System.getProperty("os.arch");
+ Log.d(TAG, "os.arch=" + arch);
+ if ("x86_64".equals(arch)) {
+ // Override the fake 16K page size from cf_x86_64_pgagnostic. The real page size on
+ // x86_64 is always 4K. This test needs the real page size because it is testing I/O
+ // error reporting behavior that is dependent on the real page size.
+ return 4096;
+ }
+ return Os.sysconf(OsConstants._SC_PAGE_SIZE);
+ }
+
@Test
public void verifyFileRead() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
- // Collect indices that the backing blocks are supposed to be corrupted.
- android.os.Bundle testArgs = InstrumentationRegistry.getArguments();
+ Bundle testArgs = InstrumentationRegistry.getArguments();
assertThat(testArgs).isNotNull();
String filePath = testArgs.getString("filePath");
- String csv = testArgs.getString("brokenBlockIndicesCsv");
- Log.d(TAG, "brokenBlockIndicesCsv: " + csv);
- String[] strings = csv.split(",");
- var corrupted = new ArrayList(strings.length);
- for (int i = 0; i < strings.length; i++) {
- corrupted.add(Integer.parseInt(strings[i]));
+ String csv = testArgs.getString("brokenByteIndicesCsv");
+ Log.d(TAG, "brokenByteIndicesCsv: " + csv);
+
+ // Build the set of pages that contain a corrupted byte.
+ final long pageSize = getPageSize();
+ Set<Long> corruptedPageIndices = new HashSet();
+ for (String s : csv.split(",")) {
+ long byteIndex = Long.parseLong(s);
+ long pageIndex = byteIndex / pageSize;
+ corruptedPageIndices.add(pageIndex);
}
-
- // Expect the read to succeed or fail per the prior.
- try (var file = new RandomAccessFile(filePath, "r")) {
- long total_blocks = (file.length() + BLOCK_SIZE - 1) / BLOCK_SIZE;
- for (int i = 0; i < (int) total_blocks; i++) {
- file.seek(i * BLOCK_SIZE);
- if (corrupted.contains(i)) {
- Log.d(TAG, "Expecting read at block #" + i + " to fail");
+ Log.d(TAG, "corruptedPageIndices=" + corruptedPageIndices);
+
+ // Read bytes from the file and verify the expected result based on the containing page.
+ // (The kernel reports fs-verity errors at page granularity.)
+ final long stride = 1024;
+ // Using a stride that is a divisor of the page size ensures that the last page is tested.
+ assertThat(pageSize % stride).isEqualTo(0);
+ try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
+ for (long byteIndex = 0; byteIndex < file.length(); byteIndex += stride) {
+ file.seek(byteIndex);
+ long pageIndex = byteIndex / pageSize;
+ if (corruptedPageIndices.contains(pageIndex)) {
+ Log.d(TAG, "Expecting read at byte #" + byteIndex + " to fail");
assertThrows(IOException.class, () -> file.read());
} else {
+ Log.d(TAG, "Expecting read at byte #" + byteIndex + " to succeed");
assertThat(file.readByte()).isEqualTo('1');
}
}
diff --git a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
index b1d6e96dca9b..88d9e9e08dce 100644
--- a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
+++ b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
@@ -33,13 +33,12 @@ import org.junit.runner.RunWith;
/**
* This test verifies fs-verity works end-to-end. There is a corresponding helper app.
*
- * <p>The helper app uses a FileIntegrityManager API to enable fs-verity to a file. The host test
- * here * tampers with the file's backing storage, then tells the helper app to read and expect
+ * <p>The helper app uses a FileIntegrityManager API to enable fs-verity on a file. The host test
+ * here tampers with the file's backing storage, then tells the helper app to read and expect
* success/failure on read.
*
- * <p>In order to make sure a block of the file is readable only if the underlying block on disk
- * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical
- * address against the block device.
+ * <p>Since the filesystem by design provides no way to corrupt fs-verity files itself, the test
+ * needs to bypass the filesystem and write directly to the block device to corrupt the files.
*/
@RootPermissionTest
@RunWith(DeviceJUnit4ClassRunner.class)
@@ -57,7 +56,7 @@ public class FsVerityHostTest extends BaseHostJUnit4Test {
BlockDeviceWriter.damageFileAgainstBlockDevice(device, getTargetFilePath(), 8192);
BlockDeviceWriter.dropCaches(device);
- verifyRead(getTargetFilePath(), "0,2");
+ verifyRead(getTargetFilePath(), "0,8192");
}
@Test
@@ -70,7 +69,7 @@ public class FsVerityHostTest extends BaseHostJUnit4Test {
BlockDeviceWriter.damageFileAgainstBlockDevice(device, getTargetFilePath(), 128 * 4096 + 1);
BlockDeviceWriter.dropCaches(device);
- verifyRead(getTargetFilePath(), "1,100,128");
+ verifyRead(getTargetFilePath(), "4096,409600,524289");
}
private String getTargetFilePath() throws DeviceNotAvailableException {
@@ -87,11 +86,17 @@ public class FsVerityHostTest extends BaseHostJUnit4Test {
assertThat(runDeviceTests(options)).isTrue();
}
+ /**
+ * Verifies the read success/failure expectation given the corrupted byte indices in the file.
+ *
+ * @param path the remote file path to read.
+ * @param indicesCsv a comma-separated list of indices of bytes that were corrupted.
+ */
private void verifyRead(String path, String indicesCsv) throws Exception {
DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE);
options.setTestClassName(TARGET_PACKAGE + ".Helper");
options.setTestMethodName("verifyFileRead");
- options.addInstrumentationArg("brokenBlockIndicesCsv", indicesCsv);
+ options.addInstrumentationArg("brokenByteIndicesCsv", indicesCsv);
options.addInstrumentationArg("filePath", getTargetFilePath());
assertThat(runDeviceTests(options)).isTrue();
}
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index 5ad1d1dce324..205fdb119a78 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -17,9 +17,7 @@ android_test {
// For access hidden connectivity methods in tests
defaults: ["framework-connectivity-test-defaults"],
- // Tethering module is released in R so this test needs to be installable
- // on R
- min_sdk_version: "30",
+ min_sdk_version: "36",
srcs: [
"java/**/*.java",
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
index 6e8b4ac48816..c940eeff8948 100644
--- a/tests/vcn/AndroidManifest.xml
+++ b/tests/vcn/AndroidManifest.xml
@@ -16,8 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.tests.vcn">
- <!-- TODO: b/374174952 Use 36 after Android B finalization -->
- <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="35" />
+
+ <uses-sdk android:minSdkVersion="36" android:targetSdkVersion="36" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
index 9c8362f36cb2..ffb79adf906b 100644
--- a/tests/vcn/AndroidTest.xml
+++ b/tests/vcn/AndroidTest.xml
@@ -27,6 +27,8 @@
class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
<option name="mainline-module-package-name" value="com.google.android.tethering" />
</object>
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.Sdk36ModuleController" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.frameworks.tests.vcn" />
diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
index 0fa11ae1fe7d..95205f4fd790 100644
--- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
@@ -23,12 +23,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
-import android.os.Build;
-
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -36,10 +32,7 @@ import org.junit.runner.RunWith;
import java.util.HashSet;
import java.util.Set;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
index fa97de0aff45..73a0a6183cb6 100644
--- a/tests/vcn/java/android/net/vcn/VcnConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
@@ -29,14 +29,11 @@ import static org.mockito.Mockito.mock;
import android.annotation.NonNull;
import android.content.Context;
-import android.os.Build;
import android.os.Parcel;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
@@ -45,10 +42,7 @@ import org.junit.runner.RunWith;
import java.util.Collections;
import java.util.Set;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnConfigTest {
private static final String TEST_PACKAGE_NAME = VcnConfigTest.class.getPackage().getName();
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 990cc74caf6c..59dc68900100 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -34,13 +34,10 @@ import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,10 +49,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionConfigTest {
// Public for use in VcnGatewayConnectionTest
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 1739fbc0fa6d..ecb177e81ef3 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -38,13 +38,10 @@ import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager.VcnStatusCallback;
import android.net.vcn.VcnManager.VcnStatusCallbackBinder;
import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;
-import android.os.Build;
import android.os.ParcelUuid;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
@@ -55,10 +52,7 @@ import java.net.UnknownHostException;
import java.util.UUID;
import java.util.concurrent.Executor;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnManagerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 52952eb3f2cc..1d57cf2bfbd5 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -30,23 +30,17 @@ import static org.junit.Assert.fail;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
-import android.os.Build;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnTransportInfoTest {
private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index c82d2003dbf6..891298a32e7d 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -22,20 +22,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import android.net.NetworkCapabilities;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnUnderlyingNetworkPolicyTest {
private static final VcnUnderlyingNetworkPolicy DEFAULT_NETWORK_POLICY =
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
index 22361cc71f12..2110d6ee7c86 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
@@ -22,20 +22,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.net.TelephonyNetworkSpecifier;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnUnderlyingNetworkSpecifierTest {
private static final int[] TEST_SUB_IDS = new int[] {1, 2, 3, 5};
diff --git a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
index fb040d8f9b91..0c3f9fedac05 100644
--- a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
@@ -30,12 +30,9 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.wifi.WifiInfo;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
@@ -44,10 +41,7 @@ import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Collections;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnUtilsTest {
private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
index 2c072e1cbc88..dbbfd83eab59 100644
--- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
@@ -22,22 +22,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.os.Build;
-
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Set;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final String SSID = "TestWifi";
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
index 01e9ac2ac3cf..bc8e9d3200b6 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
@@ -21,14 +21,11 @@ import static android.telephony.TelephonyManager.APPTYPE_USIM;
import static org.junit.Assert.assertEquals;
import android.net.eap.EapSessionConfig;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,10 +35,7 @@ import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class EapSessionConfigUtilsTest {
private static final byte[] EAP_ID = "test@android.net".getBytes(StandardCharsets.US_ASCII);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
index 821e5a6c94cb..4f3930f9b5af 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
@@ -25,13 +25,10 @@ import android.net.ipsec.ike.IkeIpv4AddrIdentification;
import android.net.ipsec.ike.IkeIpv6AddrIdentification;
import android.net.ipsec.ike.IkeKeyIdIdentification;
import android.net.ipsec.ike.IkeRfc822AddrIdentification;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,10 +39,7 @@ import java.net.InetAddress;
import javax.security.auth.x500.X500Principal;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class IkeIdentificationUtilsTest {
private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeIdentification id) {
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index 7200aee1c012..9f7d2390938f 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -29,16 +29,14 @@ import android.net.InetAddresses;
import android.net.eap.EapSessionConfig;
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSessionParams;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,10 +52,7 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class IkeSessionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
index 957e785d70c0..28cf38a2a583 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
@@ -20,23 +20,17 @@ import static org.junit.Assert.assertEquals;
import android.net.InetAddresses;
import android.net.ipsec.ike.IkeTrafficSelector;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.InetAddress;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class IkeTrafficSelectorUtilsTest {
private static final int START_PORT = 16;
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 1e8f5ff2dc07..664044a9e7d4 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -21,21 +21,15 @@ import static org.junit.Assert.assertEquals;
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeSaProposal;
import android.net.ipsec.ike.SaProposal;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class SaProposalUtilsTest {
/** Package private so that IkeSessionParamsUtilsTest can use it */
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
index 7d17724112ec..f9dc9eb4d5ae 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
@@ -20,20 +20,14 @@ import static org.junit.Assert.assertEquals;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class TunnelConnectionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
index 3d7348a79b8c..e0b5f0ef0381 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
@@ -25,13 +25,10 @@ import android.net.InetAddresses;
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeTrafficSelector;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,10 +37,7 @@ import java.net.Inet4Address;
import java.net.Inet6Address;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class TunnelModeChildSessionParamsUtilsTest {
// Package private for use in EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
index 99c7aa72146b..47638b002f37 100644
--- a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
@@ -33,12 +33,9 @@ import static org.junit.Assert.assertTrue;
import static java.util.Collections.emptyList;
import android.net.ipsec.ike.ChildSaProposal;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,10 +43,7 @@ import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class MtuUtilsTest {
private void verifyUnderlyingMtuZero(boolean isIpv4) {
diff --git a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
index f7786af840ee..c84e60086b37 100644
--- a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
@@ -21,13 +21,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,10 +35,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class PersistableBundleUtilsTest {
private static final String TEST_KEY = "testKey";
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3cccbc419425..02400ead5146 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -95,6 +95,7 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.VcnManagementService.VcnStatusCallbackInfo;
@@ -102,8 +103,6 @@ import com.android.server.vcn.TelephonySubscriptionTracker;
import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Rule;
@@ -120,10 +119,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnManagementServiceTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 6276be27fbf5..6a4a1bd3aba3 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -54,7 +54,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.vcn.VcnManager;
-import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -70,10 +69,9 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.HandlerExecutor;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -89,10 +87,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class TelephonySubscriptionTrackerTest {
private static final String PACKAGE_NAME =
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index a34908051360..bf0c46c60f68 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -70,18 +70,16 @@ import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.VcnTransportInfo;
import android.net.vcn.util.MtuUtils;
-import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration;
import com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -96,10 +94,7 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
private static final int PARALLEL_SA_COUNT = 4;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index e1a572e7a481..c946680db73f 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -26,22 +26,16 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.net.ipsec.ike.IkeSessionParams;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectionTestBase {
private VcnIkeSession mIkeSession;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index 7cfaf5be5111..0b470b9a35d0 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -30,21 +30,15 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.net.IpSecManager;
-import android.os.Build;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 9132d830c54e..bfcc4ca48313 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -23,21 +23,14 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.os.Build;
-
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index d5ef4e028709..e6fe509d1665 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -27,21 +27,14 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.os.Build;
-
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnectionTestBase {
private long mFirstRetryInterval;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 5283322682ee..2a2d5ba2ef4d 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -61,17 +61,15 @@ import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
-import android.os.Build;
import android.os.ParcelUuid;
import android.os.Process;
import android.telephony.SubscriptionInfo;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -89,10 +87,7 @@ import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
private static final int TEST_UID = Process.myUid() + 1;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index 0185931d628f..4f705d62f155 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -29,14 +29,12 @@ import android.annotation.NonNull;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkRequest;
-import android.os.Build;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -46,10 +44,7 @@ import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
import java.util.List;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnNetworkProviderTest {
private static final int TEST_SCORE_UNSATISFIED = 0;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index c12adcbab08a..1853b6b59f5d 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -49,7 +49,6 @@ import android.net.Uri;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
-import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.provider.Settings;
@@ -57,14 +56,13 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -79,10 +77,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class VcnTest {
private static final String PKG_NAME = VcnTest.class.getPackage().getName();
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
index 53a36d3e4d6a..224b45ced965 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
@@ -44,18 +44,16 @@ import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.net.IpSecTransformState;
-import android.os.Build;
import android.os.OutcomeReceiver;
import android.os.PowerManager;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult;
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -69,10 +67,7 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
private static final String TAG = IpSecPacketLossDetectorTest.class.getSimpleName();
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index a9c637f7c943..16dbab9d7a61 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -42,14 +42,11 @@ import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
-import android.os.Build;
import android.os.PersistableBundle;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
@@ -59,10 +56,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class NetworkPriorityClassifierTest extends NetworkEvaluationTestBase {
private UnderlyingNetworkRecord mWifiNetworkRecord;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
index 99c508c139ec..b67a2fd21b40 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
@@ -58,7 +58,6 @@ import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
import android.net.vcn.VcnCellUnderlyingNetworkTemplateTest;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
-import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.telephony.CarrierConfigManager;
@@ -67,6 +66,7 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.VcnContext;
@@ -76,8 +76,6 @@ import com.android.server.vcn.routeselection.UnderlyingNetworkController.Network
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkControllerCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkListener;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -95,10 +93,7 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class UnderlyingNetworkControllerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
index 3ca84cf05cd1..850f9aa963d0 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
@@ -37,15 +37,13 @@ import static org.mockito.Mockito.when;
import android.net.IpSecTransform;
import android.net.vcn.VcnGatewayConnectionConfig;
-import android.os.Build;
import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.Dependencies;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -56,10 +54,7 @@ import org.mockito.Mock;
import java.util.concurrent.TimeUnit;
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class UnderlyingNetworkEvaluatorTest extends NetworkEvaluationTestBase {
private static final int PENALTY_TIMEOUT_MIN = 10;