summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java4
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java3
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java6
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java15
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java3
-rw-r--r--cmds/screencap/screencap.cpp39
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/Android.bp11
-rw-r--r--core/java/android/app/Activity.java10
-rw-r--r--core/java/android/app/ActivityManager.java45
-rw-r--r--core/java/android/app/AppOpsManager.java28
-rw-r--r--core/java/android/app/Notification.java50
-rw-r--r--core/java/android/app/Person.java14
-rw-r--r--core/java/android/app/ServiceStartArgs.java2
-rw-r--r--core/java/android/app/StatusBarManager.java36
-rw-r--r--core/java/android/app/WallpaperInfo.java8
-rw-r--r--core/java/android/app/WallpaperManager.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java1
-rw-r--r--core/java/android/content/ContentCaptureOptions.java225
-rw-r--r--core/java/android/content/pm/PackageInstaller.java4
-rw-r--r--core/java/android/content/pm/TEST_MAPPING333
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java7
-rw-r--r--core/java/android/hardware/input/InputSettings.java2
-rw-r--r--core/java/android/hardware/lights/Light.java30
-rw-r--r--core/java/android/inputmethodservice/NavigationBarController.java100
-rw-r--r--core/java/android/net/VpnManager.java2
-rw-r--r--core/java/android/os/UserManager.java8
-rw-r--r--core/java/android/service/contentcapture/ContentCaptureService.java12
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java4
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java2
-rw-r--r--core/java/android/speech/SpeechRecognizer.java4
-rw-r--r--core/java/android/view/InsetsController.java14
-rw-r--r--core/java/android/view/InsetsFrameProvider.java4
-rw-r--r--core/java/android/view/InsetsSource.java43
-rw-r--r--core/java/android/view/InsetsState.java3
-rw-r--r--core/java/android/view/MotionEvent.java24
-rw-r--r--core/java/android/view/SurfaceControl.java14
-rw-r--r--core/java/android/view/SurfaceControlRegistry.java2
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java3
-rw-r--r--core/java/android/view/View.java11
-rw-r--r--core/java/android/view/Window.java9
-rw-r--r--core/java/android/view/WindowManager.java34
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java39
-rw-r--r--core/java/android/view/contentcapture/OWNERS3
-rw-r--r--core/java/android/view/contentprotection/ContentProtectionUtils.java60
-rw-r--r--core/java/android/view/contentprotection/OWNERS4
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java13
-rw-r--r--core/java/android/view/inputmethod/TextAppearanceInfo.java5
-rw-r--r--core/java/android/widget/RemoteViews.java31
-rw-r--r--core/java/android/window/SnapshotDrawerUtils.java33
-rw-r--r--core/java/android/window/SurfaceSyncGroup.java8
-rw-r--r--core/java/android/window/TaskSnapshot.java24
-rw-r--r--core/java/android/window/TransitionInfo.java4
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java6
-rw-r--r--core/java/com/android/internal/accessibility/common/MagnificationConstants.java6
-rw-r--r--core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java6
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java5
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java2
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java22
-rw-r--r--core/java/com/android/internal/os/anr/AnrLatencyTracker.java35
-rw-r--r--core/java/com/android/internal/protolog/common/ProtoLog.java20
-rw-r--r--core/java/com/android/internal/util/LatencyTracker.java48
-rw-r--r--core/java/com/android/internal/widget/ImageFloatingTextView.java2
-rw-r--r--core/proto/android/companion/telecom.proto8
-rw-r--r--core/proto/android/input/keyboard_configured.proto50
-rw-r--r--core/res/res/layout/language_picker_section_header.xml3
-rw-r--r--core/res/res/values-af/strings.xml1
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-as/strings.xml20
-rw-r--r--core/res/res/values-az/strings.xml1
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml5
-rw-r--r--core/res/res/values-be/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml1
-rw-r--r--core/res/res/values-bn/strings.xml19
-rw-r--r--core/res/res/values-bs/strings.xml21
-rw-r--r--core/res/res/values-ca/strings.xml5
-rw-r--r--core/res/res/values-cs/strings.xml5
-rw-r--r--core/res/res/values-da/strings.xml3
-rw-r--r--core/res/res/values-de/strings.xml3
-rw-r--r--core/res/res/values-el/strings.xml1
-rw-r--r--core/res/res/values-en-rAU/strings.xml1
-rw-r--r--core/res/res/values-en-rCA/strings.xml1
-rw-r--r--core/res/res/values-en-rGB/strings.xml1
-rw-r--r--core/res/res/values-en-rIN/strings.xml1
-rw-r--r--core/res/res/values-en-rXC/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml13
-rw-r--r--core/res/res/values-es/strings.xml7
-rw-r--r--core/res/res/values-et/strings.xml21
-rw-r--r--core/res/res/values-eu/strings.xml45
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml1
-rw-r--r--core/res/res/values-fr-rCA/strings.xml29
-rw-r--r--core/res/res/values-fr/strings.xml9
-rw-r--r--core/res/res/values-gl/strings.xml24
-rw-r--r--core/res/res/values-gu/strings.xml20
-rw-r--r--core/res/res/values-hi/strings.xml3
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml1
-rw-r--r--core/res/res/values-hy/strings.xml1
-rw-r--r--core/res/res/values-in/strings.xml5
-rw-r--r--core/res/res/values-is/strings.xml1
-rw-r--r--core/res/res/values-it/strings.xml31
-rw-r--r--core/res/res/values-iw/strings.xml7
-rw-r--r--core/res/res/values-ja/strings.xml5
-rw-r--r--core/res/res/values-ka/strings.xml23
-rw-r--r--core/res/res/values-kk/strings.xml19
-rw-r--r--core/res/res/values-km/strings.xml7
-rw-r--r--core/res/res/values-kn/strings.xml45
-rw-r--r--core/res/res/values-ko/strings.xml1
-rw-r--r--core/res/res/values-ky/strings.xml23
-rw-r--r--core/res/res/values-lo/strings.xml1
-rw-r--r--core/res/res/values-lt/strings.xml3
-rw-r--r--core/res/res/values-lv/strings.xml22
-rw-r--r--core/res/res/values-mcc310-mnc030-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc170-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc280-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc380-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc410-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc560-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc950-eu/strings.xml2
-rw-r--r--core/res/res/values-mcc311-mnc180-eu/strings.xml2
-rw-r--r--core/res/res/values-mk/strings.xml14
-rw-r--r--core/res/res/values-ml/strings.xml19
-rw-r--r--core/res/res/values-mn/strings.xml19
-rw-r--r--core/res/res/values-mr/strings.xml23
-rw-r--r--core/res/res/values-ms/strings.xml3
-rw-r--r--core/res/res/values-my/strings.xml25
-rw-r--r--core/res/res/values-nb/strings.xml19
-rw-r--r--core/res/res/values-ne/strings.xml31
-rw-r--r--core/res/res/values-nl/strings.xml1
-rw-r--r--core/res/res/values-or/strings.xml33
-rw-r--r--core/res/res/values-pa/strings.xml21
-rw-r--r--core/res/res/values-pl/strings.xml29
-rw-r--r--core/res/res/values-pt-rBR/strings.xml1
-rw-r--r--core/res/res/values-pt-rPT/strings.xml5
-rw-r--r--core/res/res/values-pt/strings.xml1
-rw-r--r--core/res/res/values-ro/strings.xml1
-rw-r--r--core/res/res/values-ru/strings.xml1
-rw-r--r--core/res/res/values-si/strings.xml1
-rw-r--r--core/res/res/values-sk/strings.xml2
-rw-r--r--core/res/res/values-sl/strings.xml25
-rw-r--r--core/res/res/values-sq/strings.xml5
-rw-r--r--core/res/res/values-sr/strings.xml5
-rw-r--r--core/res/res/values-sv/strings.xml1
-rw-r--r--core/res/res/values-sw/strings.xml7
-rw-r--r--core/res/res/values-ta/strings.xml21
-rw-r--r--core/res/res/values-te/strings.xml11
-rw-r--r--core/res/res/values-th/strings.xml1
-rw-r--r--core/res/res/values-tl/strings.xml1
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur/strings.xml20
-rw-r--r--core/res/res/values-uz/strings.xml1
-rw-r--r--core/res/res/values-vi/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml9
-rw-r--r--core/res/res/values-zh-rHK/strings.xml3
-rw-r--r--core/res/res/values-zh-rTW/strings.xml19
-rw-r--r--core/res/res/values-zu/strings.xml1
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityManagerTest.java6
-rw-r--r--core/tests/coretests/src/android/content/ContentCaptureOptionsTest.java94
-rw-r--r--core/tests/coretests/src/android/content/OWNERS2
-rw-r--r--core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java4
-rw-r--r--core/tests/coretests/src/android/content/res/TEST_MAPPING13
-rw-r--r--core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java12
-rw-r--r--core/tests/coretests/src/android/view/contentprotection/ContentProtectionUtilsTest.java111
-rw-r--r--core/tests/coretests/src/android/view/contentprotection/OWNERS4
-rw-r--r--core/tests/coretests/src/android/view/inputmethod/TextAppearanceInfoTest.java83
-rw-r--r--core/tests/coretests/src/android/widget/RemoteViewsTest.java77
-rw-r--r--core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java31
-rw-r--r--core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java260
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--graphics/java/android/graphics/GraphicBuffer.java5
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java49
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java51
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java14
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java45
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java6
-rw-r--r--libs/WindowManager/Shell/res/drawable/bubble_manage_menu_section.xml24
-rw-r--r--libs/WindowManager/Shell/res/drawable/ic_expand_less.xml25
-rw-r--r--libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml41
-rw-r--r--libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml77
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/colors.xml1
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java60
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java77
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java145
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java242
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt90
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java187
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java71
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java173
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java64
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java50
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java5
-rw-r--r--libs/WindowManager/Shell/tests/flicker/Android.bp1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml86
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt111
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt67
-rw-r--r--libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockToken.java (renamed from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java)8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/LaunchAdjacentControllerTest.kt172
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java121
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt13
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java3
-rw-r--r--libs/androidfw/CursorWindow.cpp10
-rw-r--r--libs/androidfw/include/androidfw/CursorWindow.h3
-rw-r--r--libs/androidfw/tests/CursorWindow_test.cpp31
-rw-r--r--libs/hwui/Properties.cpp14
-rw-r--r--libs/hwui/Properties.h2
-rw-r--r--libs/hwui/renderthread/VulkanManager.cpp52
-rw-r--r--libs/hwui/renderthread/VulkanManager.h23
-rw-r--r--libs/hwui/tests/common/TestUtils.h46
-rw-r--r--media/java/android/media/MediaCodec.java7
-rw-r--r--media/java/android/media/MediaRoute2ProviderService.java12
-rw-r--r--media/java/android/media/RouteListingPreference.java16
-rw-r--r--media/java/android/media/tv/TvInputService.java14
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppService.java15
-rw-r--r--media/jni/android_media_ImageReader.cpp1
-rw-r--r--packages/CarrierDefaultApp/assets/slice_purchase_test.html12
-rw-r--r--packages/CarrierDefaultApp/assets/slice_purchase_test.js16
-rw-r--r--packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java (renamed from packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java)37
-rw-r--r--packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java37
-rw-r--r--packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java29
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-az/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rAU/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rGB/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rIN/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-hr/strings.xml22
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml22
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml22
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-mn/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml22
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml22
-rw-r--r--packages/CompanionDeviceManager/res/values-ro/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-sr/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml20
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-tl/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml26
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml18
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml18
-rw-r--r--packages/CredentialManager/res/values-am/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-az/strings.xml20
-rw-r--r--packages/CredentialManager/res/values-bg/strings.xml22
-rw-r--r--packages/CredentialManager/res/values-cs/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-fr-rCA/strings.xml4
-rw-r--r--packages/CredentialManager/res/values-hr/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-kk/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-ky/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-lt/strings.xml22
-rw-r--r--packages/CredentialManager/res/values-mk/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-ms/strings.xml4
-rw-r--r--packages/CredentialManager/res/values-nb/strings.xml22
-rw-r--r--packages/CredentialManager/res/values-or/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-pt/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-sl/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-sq/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-sw/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-tl/strings.xml2
-rw-r--r--packages/CredentialManager/res/values-tr/strings.xml22
-rw-r--r--packages/CredentialManager/res/values-uz/strings.xml14
-rw-r--r--packages/CredentialManager/res/values-vi/strings.xml24
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java5
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java7
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java6
-rw-r--r--packages/PrintSpooler/res/values-mk/strings.xml2
-rw-r--r--packages/PrintSpooler/res/values-ne/strings.xml2
-rw-r--r--packages/SettingsLib/Android.bp3
-rw-r--r--packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml2
-rw-r--r--packages/SettingsLib/ProfileSelector/res/values-te/strings.xml2
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt28
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt4
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt31
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt11
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt19
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt5
-rw-r--r--packages/SettingsLib/TEST_MAPPING13
-rw-r--r--packages/SettingsLib/Utils/res/values-as/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-bn/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-et/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-eu/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-gl/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-gu/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-it/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-ka/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-kk/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-kn/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-lv/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-ml/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-mn/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-mr/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-my/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-nb/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-ne/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-or/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-pa/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-pl/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-sl/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-ta/strings.xml20
-rw-r--r--packages/SettingsLib/Utils/res/values-ur/strings.xml20
-rw-r--r--packages/SettingsLib/res/drawable/ic_docked_tablet.xml26
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml26
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml5
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml30
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml36
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml24
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-ne/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml22
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml36
-rw-r--r--packages/SettingsLib/res/values-pa/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pl/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml20
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml10
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml6
-rw-r--r--packages/SettingsLib/res/values/strings.xml23
-rw-r--r--packages/SettingsLib/res/values/styles.xml4
-rw-r--r--packages/SettingsLib/search/Android.bp16
-rw-r--r--packages/SettingsLib/search/common.mk10
-rw-r--r--packages/SettingsLib/search/interface-src/com/android/settingslib/search/SearchIndexable.java (renamed from packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexable.java)12
-rw-r--r--packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java39
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java17
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java34
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt362
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java454
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.kt30
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java13
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java10
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java12
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java13
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java32
-rw-r--r--packages/SettingsLib/tests/unit/Android.bp35
-rw-r--r--packages/SettingsLib/tests/unit/AndroidManifest.xml29
-rw-r--r--packages/SettingsLib/tests/unit/OWNERS2
-rw-r--r--packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt195
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/TEST_MAPPING99
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/Easings.kt78
-rw-r--r--packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt46
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt187
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt313
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/ConditionalModifiers.kt52
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt27
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt9
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt13
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt2
-rw-r--r--packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java410
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt44
-rw-r--r--packages/SystemUI/proguard_common.flags19
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res-keyguard/values-ca/strings.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values-el/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-eu/strings.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-hr/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-ja/strings.xml6
-rw-r--r--packages/SystemUI/res-keyguard/values-kn/strings.xml8
-rw-r--r--packages/SystemUI/res-keyguard/values-ko/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-ky/strings.xml20
-rw-r--r--packages/SystemUI/res-keyguard/values-mk/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-mn/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-mr/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-ne/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-or/strings.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values-pl/strings.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml20
-rw-r--r--packages/SystemUI/res-keyguard/values-te/strings.xml6
-rw-r--r--packages/SystemUI/res-keyguard/values-tl/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-tr/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-ur/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values/integers.xml3
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml9
-rw-r--r--packages/SystemUI/res/layout/media_output_list_item_advanced.xml4
-rw-r--r--packages/SystemUI/res/layout/scene_window_root.xml32
-rw-r--r--packages/SystemUI/res/layout/screen_share_dialog.xml2
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml7
-rw-r--r--packages/SystemUI/res/layout/window_magnification_settings_view.xml6
-rw-r--r--packages/SystemUI/res/raw/fingerprint_dialogue_unlocked_to_checkmark_success_lottie.json1
-rw-r--r--packages/SystemUI/res/values-af/strings.xml11
-rw-r--r--packages/SystemUI/res/values-am/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml13
-rw-r--r--packages/SystemUI/res/values-as/strings.xml23
-rw-r--r--packages/SystemUI/res/values-az/strings.xml11
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml15
-rw-r--r--packages/SystemUI/res/values-be/strings.xml12
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml13
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml23
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml21
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml11
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml11
-rw-r--r--packages/SystemUI/res/values-da/strings.xml11
-rw-r--r--packages/SystemUI/res/values-de/strings.xml17
-rw-r--r--packages/SystemUI/res/values-el/strings.xml11
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml13
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml9
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml13
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml13
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml9
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml15
-rw-r--r--packages/SystemUI/res/values-es/strings.xml11
-rw-r--r--packages/SystemUI/res/values-et/strings.xml25
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml23
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml13
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml11
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml144
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml11
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml23
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml23
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml17
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml21
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml13
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml11
-rw-r--r--packages/SystemUI/res/values-in/strings.xml13
-rw-r--r--packages/SystemUI/res/values-is/strings.xml11
-rw-r--r--packages/SystemUI/res/values-it/strings.xml27
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml15
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml19
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml21
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml25
-rw-r--r--packages/SystemUI/res/values-km/strings.xml17
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml49
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml13
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml11
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml11
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml23
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml19
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml23
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml23
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml31
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml11
-rw-r--r--packages/SystemUI/res/values-my/strings.xml25
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml23
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml27
-rw-r--r--packages/SystemUI/res/values-night/colors.xml4
-rw-r--r--packages/SystemUI/res/values-night/styles.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-or/strings.xml35
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml25
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml27
-rw-r--r--packages/SystemUI/res/values-pl/tiles_states_strings.xml4
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml13
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml15
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml13
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml13
-rw-r--r--packages/SystemUI/res/values-si/strings.xml11
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml13
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml29
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml13
-rw-r--r--packages/SystemUI/res/values-sq/tiles_states_strings.xml36
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml15
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml11
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml25
-rw-r--r--packages/SystemUI/res/values-te/strings.xml21
-rw-r--r--packages/SystemUI/res/values-th/strings.xml19
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml11
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml19
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml11
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml23
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml11
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml17
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml13
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml11
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml23
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml11
-rw-r--r--packages/SystemUI/res/values/attrs.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/ids.xml6
-rw-r--r--packages/SystemUI/res/values/strings.xml10
-rw-r--r--packages/SystemUI/res/values/styles.xml6
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl14
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt63
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ClockEventController.kt92
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java21
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java13
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt27
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java13
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java15
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt78
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java175
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt80
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakefulnessModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt98
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt153
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt (renamed from packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt)20
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt65
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt86
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt70
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt (renamed from packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt)29
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java104
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/ActivityTaskManagerProxy.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java228
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt94
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt79
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt36
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt107
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt160
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt140
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java61
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java85
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt117
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt64
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt69
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt128
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt)0
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt71
-rw-r--r--packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java6
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java38
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ProxyManager.java20
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java10
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java12
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java5
-rw-r--r--services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java65
-rw-r--r--services/autofill/java/com/android/server/autofill/InlineSuggestionRequestConsumer.java55
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java293
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java24
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java9
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java80
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java128
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java45
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java50
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java154
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java4
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java209
-rw-r--r--services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java85
-rw-r--r--services/core/java/com/android/server/VpnManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java200
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java19
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/AppProfiler.java16
-rw-r--r--services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java32
-rw-r--r--services/core/java/com/android/server/am/BroadcastProcessQueue.java27
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java3
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java23
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java110
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java81
-rw-r--r--services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java33
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java12
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java45
-rw-r--r--services/core/java/com/android/server/am/ProcessServiceRecord.java3
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java23
-rw-r--r--services/core/java/com/android/server/am/UserController.java48
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java17
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java12
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java142
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java5
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java72
-rw-r--r--services/core/java/com/android/server/biometrics/TEST_MAPPING21
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java4
-rw-r--r--services/core/java/com/android/server/biometrics/log/OperationContextExt.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java16
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java31
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java50
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java112
-rw-r--r--services/core/java/com/android/server/display/BrightnessSetting.java17
-rw-r--r--services/core/java/com/android/server/display/BrightnessTracker.java1
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java7
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java24
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java89
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java133
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerControllerInterface.java14
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java16
-rw-r--r--services/core/java/com/android/server/display/NormalBrightnessModeController.java51
-rw-r--r--services/core/java/com/android/server/display/PersistentDataStore.java71
-rw-r--r--services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java10
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java21
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java34
-rw-r--r--services/core/java/com/android/server/input/InputFeatureFlagProvider.java17
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java4
-rw-r--r--services/core/java/com/android/server/input/InputSettingsObserver.java19
-rw-r--r--services/core/java/com/android/server/input/KeyboardBacklightController.java72
-rw-r--r--services/core/java/com/android/server/input/KeyboardLayoutManager.java2
-rw-r--r--services/core/java/com/android/server/input/KeyboardMetricsCollector.java162
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java25
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStorage.java5
-rw-r--r--services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java9
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2Provider.java5
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java34
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java27
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java80
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java4
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java64
-rw-r--r--services/core/java/com/android/server/notification/NotificationUsageStats.java60
-rw-r--r--services/core/java/com/android/server/notification/RateEstimator.java15
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java7
-rw-r--r--services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java53
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java37
-rw-r--r--services/core/java/com/android/server/power/Notifier.java8
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java6
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperDataParser.java2
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java13
-rw-r--r--services/core/java/com/android/server/wm/AbsAppSnapshotController.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java9
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java19
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java32
-rw-r--r--services/core/java/com/android/server/wm/AnrController.java26
-rw-r--r--services/core/java/com/android/server/wm/AppSnapshotLoader.java6
-rw-r--r--services/core/java/com/android/server/wm/AppWarnings.java68
-rw-r--r--services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java5
-rw-r--r--services/core/java/com/android/server/wm/DeprecatedAbiDialog.java58
-rw-r--r--services/core/java/com/android/server/wm/DeviceStateController.java32
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java16
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java94
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java5
-rw-r--r--services/core/java/com/android/server/wm/EventLogTags.logtags3
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java15
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java12
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java40
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java3
-rw-r--r--services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java5
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java6
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java17
-rw-r--r--services/core/java/com/android/server/wm/SnapshotPersistQueue.java5
-rw-r--r--services/core/java/com/android/server/wm/Task.java10
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java12
-rw-r--r--services/core/java/com/android/server/wm/Transition.java27
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java23
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java28
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp16
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java4
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java67
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/Owners.java10
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java2
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java192
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java14
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java23
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java69
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/am/UserControllerTest.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java89
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java141
-rw-r--r--services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java114
-rw-r--r--services/tests/servicestests/src/com/android/server/contentcapture/OWNERS4
-rw-r--r--services/tests/servicestests/src/com/android/server/contentprotection/OWNERS3
-rw-r--r--services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java127
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java49
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java110
-rw-r--r--services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java142
-rw-r--r--services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt252
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java69
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/power/NotifierTest.java31
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java119
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java3
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java94
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java72
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java21
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java38
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java1
-rw-r--r--telecomm/java/android/telecom/ParcelableConference.java12
-rw-r--r--telecomm/java/android/telecom/StatusHints.java53
-rw-r--r--tests/FlickerTests/Android.bp5
-rw-r--r--tests/FlickerTests/AndroidTestTemplate.xml90
-rw-r--r--tests/FlickerTests/manifests/AndroidManifest.xml5
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING15
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt)4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt)4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt)6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt)6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt)4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt)4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTestCfArm.kt)3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt (renamed from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt)2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt2
-rw-r--r--tests/FlickerTests/trace_config/trace_config.textproto77
-rw-r--r--tests/InputMethodStressTest/AndroidManifest.xml3
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java6
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DefaultImeVisibilityTest.java9
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java66
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java10
-rw-r--r--tools/protologtool/Android.bp2
-rw-r--r--wifi/tests/src/android/net/wifi/nl80211/OWNERS1
1132 files changed, 19636 insertions, 8170 deletions
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
index a9f720ac2ba0..515ddc8d1d49 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
@@ -80,7 +80,7 @@ public class BenchmarkRunner {
private void prepareForNextRun() {
SystemClock.sleep(COOL_OFF_PERIOD_MS);
- ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+ ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers");
mStartTimeNs = System.nanoTime();
mPausedDurationNs = 0;
}
@@ -102,7 +102,7 @@ public class BenchmarkRunner {
* to avoid unnecessary waiting.
*/
public void resumeTiming() {
- ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+ ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers");
resumeTimer();
}
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 19a47669b0dd..6dba5b3517f7 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -1541,7 +1541,8 @@ public class UserLifecycleTests {
private void waitForBroadcastIdle() {
try {
- ShellHelper.runShellCommandWithTimeout("am wait-for-broadcast-idle", TIMEOUT_IN_SECOND);
+ ShellHelper.runShellCommandWithTimeout(
+ "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECOND);
} catch (TimeoutException e) {
Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 92fc78e273ed..4f5eb37d871d 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1598,7 +1598,7 @@ public class JobSchedulerService extends com.android.server.SystemService
uId, null, jobStatus.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN, jobStatus.getStandbyBucket(),
- jobStatus.getJobId(),
+ jobStatus.getLoggingJobId(),
jobStatus.hasChargingConstraint(),
jobStatus.hasBatteryNotLowConstraint(),
jobStatus.hasStorageNotLowConstraint(),
@@ -2026,7 +2026,7 @@ public class JobSchedulerService extends com.android.server.SystemService
cancelled.getSourceUid(), null, cancelled.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__CANCELLED,
internalReasonCode, cancelled.getStandbyBucket(),
- cancelled.getJobId(),
+ cancelled.getLoggingJobId(),
cancelled.hasChargingConstraint(),
cancelled.hasBatteryNotLowConstraint(),
cancelled.hasStorageNotLowConstraint(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index bf2e4560a4ef..90f1523104ee 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -465,7 +465,8 @@ public final class JobServiceContext implements ServiceConnection {
job.getSourceUid(), null, job.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN,
- job.getStandbyBucket(), job.getJobId(),
+ job.getStandbyBucket(),
+ job.getLoggingJobId(),
job.hasChargingConstraint(),
job.hasBatteryNotLowConstraint(),
job.hasStorageNotLowConstraint(),
@@ -1521,7 +1522,8 @@ public final class JobServiceContext implements ServiceConnection {
FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
completedJob.getSourceUid(), null, completedJob.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
- loggingInternalStopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
+ loggingInternalStopReason, completedJob.getStandbyBucket(),
+ completedJob.getLoggingJobId(),
completedJob.hasChargingConstraint(),
completedJob.hasBatteryNotLowConstraint(),
completedJob.hasStorageNotLowConstraint(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index b5d763c17e59..a8b4c695889c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -231,6 +231,8 @@ public final class JobStatus {
final String sourceTag;
@Nullable
private final String mNamespace;
+ /** An ID that can be used to uniquely identify the job when logging statsd metrics. */
+ private final long mLoggingJobId;
final String tag;
@@ -568,6 +570,7 @@ public final class JobStatus {
this.callingUid = callingUid;
this.standbyBucket = standbyBucket;
mNamespace = namespace;
+ mLoggingJobId = generateLoggingId(namespace, job.getId());
int tempSourceUid = -1;
if (sourceUserId != -1 && sourcePackageName != null) {
@@ -804,6 +807,13 @@ public final class JobStatus {
/*innerFlags=*/ 0, /* dynamicConstraints */ 0);
}
+ private long generateLoggingId(@Nullable String namespace, int jobId) {
+ if (namespace == null) {
+ return jobId;
+ }
+ return ((long) namespace.hashCode()) << 31 | jobId;
+ }
+
public void enqueueWorkLocked(JobWorkItem work) {
if (pendingWork == null) {
pendingWork = new ArrayList<>();
@@ -956,6 +966,11 @@ public final class JobStatus {
return job.getId();
}
+ /** Returns an ID that can be used to uniquely identify the job when logging statsd metrics. */
+ public long getLoggingJobId() {
+ return mLoggingJobId;
+ }
+
public void printUniqueId(PrintWriter pw) {
if (mNamespace != null) {
pw.print(mNamespace);
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 175c8d1cc4f3..07958dd0fef5 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
@@ -3153,7 +3153,8 @@ public final class QuotaController extends StateController {
private static final int DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 20;
private static final long DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS = 5000; // 5 seconds
private static final long DEFAULT_MIN_QUOTA_CHECK_DELAY_MS = MINUTE_IN_MILLIS;
- private static final long DEFAULT_EJ_LIMIT_EXEMPTED_MS = 45 * MINUTE_IN_MILLIS;
+ // TODO(267949143): set a different limit for headless system apps
+ private static final long DEFAULT_EJ_LIMIT_EXEMPTED_MS = 60 * MINUTE_IN_MILLIS;
private static final long DEFAULT_EJ_LIMIT_ACTIVE_MS = 30 * MINUTE_IN_MILLIS;
private static final long DEFAULT_EJ_LIMIT_WORKING_MS = DEFAULT_EJ_LIMIT_ACTIVE_MS;
private static final long DEFAULT_EJ_LIMIT_FREQUENT_MS = 10 * MINUTE_IN_MILLIS;
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index d7222d248911..863efffe3807 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -30,6 +30,8 @@
#include <binder/ProcessState.h>
+#include <ftl/concat.h>
+#include <ftl/optional.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
@@ -45,14 +47,7 @@ using namespace android;
#define COLORSPACE_SRGB 1
#define COLORSPACE_DISPLAY_P3 2
-static void usage(const char* pname, std::optional<PhysicalDisplayId> displayId)
-{
- std::string defaultDisplayStr = "";
- if (!displayId) {
- defaultDisplayStr = "";
- } else {
- defaultDisplayStr = " (default: " + to_string(*displayId) + ")";
- }
+void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) {
fprintf(stderr,
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
" -h: this message\n"
@@ -61,7 +56,13 @@ static void usage(const char* pname, std::optional<PhysicalDisplayId> displayId)
" see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
"If FILENAME ends with .png it will be saved as a png.\n"
"If FILENAME is not given, the results will be printed to stdout.\n",
- pname, defaultDisplayStr.c_str());
+ pname,
+ displayIdOpt
+ .transform([](DisplayId id) {
+ return std::string(ftl::Concat(" (default: ", id.value, ')').str());
+ })
+ .value_or(std::string())
+ .c_str());
}
static int32_t flinger2bitmapFormat(PixelFormat f)
@@ -132,7 +133,7 @@ int main(int argc, char** argv)
fprintf(stderr, "Failed to get ID for any displays.\n");
return 1;
}
- std::optional<PhysicalDisplayId> displayId;
+ std::optional<DisplayId> displayIdOpt;
const char* pname = argv[0];
bool png = false;
int c;
@@ -142,8 +143,8 @@ int main(int argc, char** argv)
png = true;
break;
case 'd':
- displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
- if (!displayId) {
+ displayIdOpt = DisplayId::fromValue(atoll(optarg));
+ if (!displayIdOpt) {
fprintf(stderr, "Invalid display ID: %s\n", optarg);
return 1;
}
@@ -151,15 +152,15 @@ int main(int argc, char** argv)
case '?':
case 'h':
if (ids.size() == 1) {
- displayId = ids.front();
- }
- usage(pname, displayId);
+ displayIdOpt = ids.front();
+ }
+ usage(pname, displayIdOpt);
return 1;
}
}
- if (!displayId) { // no diplsay id is specified
- displayId = ids.front();
+ if (!displayIdOpt) {
+ displayIdOpt = ids.front();
if (ids.size() > 1) {
fprintf(stderr,
"[Warning] Multiple displays were found, but no display id was specified! "
@@ -191,7 +192,7 @@ int main(int argc, char** argv)
}
if (fd == -1) {
- usage(pname, displayId);
+ usage(pname, displayIdOpt);
return 1;
}
@@ -208,7 +209,7 @@ int main(int argc, char** argv)
ProcessState::self()->startThreadPool();
sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- status_t result = ScreenshotClient::captureDisplay(*displayId, captureListener);
+ status_t result = ScreenshotClient::captureDisplay(*displayIdOpt, captureListener);
if (result != NO_ERROR) {
close(fd);
return 1;
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 9eb9d66cb71a..9bd29700a12d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3568,6 +3568,8 @@ package android.view {
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int FLAG_SLIPPERY = 536870912; // 0x20000000
field public CharSequence accessibilityTitle;
+ field public float preferredMaxDisplayRefreshRate;
+ field public float preferredMinDisplayRefreshRate;
field public int privateFlags;
}
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 02b14ad7a757..f8f4cc3523f2 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -510,6 +510,17 @@ filegroup {
],
}
+// common protolog sources without classes that rely on Android SDK
+filegroup {
+ name: "protolog-common-no-android-src",
+ srcs: [
+ ":protolog-common-src",
+ ],
+ exclude_srcs: [
+ "com/android/internal/protolog/common/ProtoLog.java",
+ ],
+}
+
java_library {
name: "protolog-lib",
platform_apis: true,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 81258f1a61da..6e0fc4f53a23 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1084,6 +1084,16 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Update the forced status bar appearance.
+ * @hide
+ */
+ @Override
+ public void updateStatusBarAppearance(int appearance) {
+ mTaskDescription.setStatusBarAppearance(appearance);
+ setTaskDescription(mTaskDescription);
+ }
+
+ /**
* Update the forced navigation bar color.
* @hide
*/
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b5ee895a5a01..ff0f437ea8a1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -81,6 +81,7 @@ import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.Singleton;
import android.util.Size;
+import android.view.WindowInsetsController.Appearance;
import android.window.TaskSnapshot;
import com.android.internal.app.LocalePicker;
@@ -1553,6 +1554,8 @@ public class ActivityManager {
private int mColorBackgroundFloating;
private int mStatusBarColor;
private int mNavigationBarColor;
+ @Appearance
+ private int mStatusBarAppearance;
private boolean mEnsureStatusBarContrastWhenTransparent;
private boolean mEnsureNavigationBarContrastWhenTransparent;
private int mResizeMode;
@@ -1653,8 +1656,8 @@ public class ActivityManager {
final Icon icon = mIconRes == Resources.ID_NULL ? null :
Icon.createWithResource(ActivityThread.currentPackageName(), mIconRes);
return new TaskDescription(mLabel, icon, mPrimaryColor, mBackgroundColor,
- mStatusBarColor, mNavigationBarColor, false, false, RESIZE_MODE_RESIZEABLE,
- -1, -1, 0);
+ mStatusBarColor, mNavigationBarColor, 0, false, false,
+ RESIZE_MODE_RESIZEABLE, -1, -1, 0);
}
}
@@ -1672,7 +1675,7 @@ public class ActivityManager {
@Deprecated
public TaskDescription(String label, @DrawableRes int iconRes, int colorPrimary) {
this(label, Icon.createWithResource(ActivityThread.currentPackageName(), iconRes),
- colorPrimary, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ colorPrimary, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
throw new RuntimeException("A TaskDescription's primary color should be opaque");
}
@@ -1690,7 +1693,7 @@ public class ActivityManager {
@Deprecated
public TaskDescription(String label, @DrawableRes int iconRes) {
this(label, Icon.createWithResource(ActivityThread.currentPackageName(), iconRes),
- 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ 0, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
}
/**
@@ -1702,7 +1705,7 @@ public class ActivityManager {
*/
@Deprecated
public TaskDescription(String label) {
- this(label, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ this(label, null, 0, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
}
/**
@@ -1712,7 +1715,7 @@ public class ActivityManager {
*/
@Deprecated
public TaskDescription() {
- this(null, null, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ this(null, null, 0, 0, 0, 0, 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
}
/**
@@ -1728,7 +1731,7 @@ public class ActivityManager {
@Deprecated
public TaskDescription(String label, Bitmap icon, int colorPrimary) {
this(label, icon != null ? Icon.createWithBitmap(icon) : null, colorPrimary, 0, 0, 0,
- false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ 0, false, false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
throw new RuntimeException("A TaskDescription's primary color should be opaque");
}
@@ -1744,14 +1747,15 @@ public class ActivityManager {
*/
@Deprecated
public TaskDescription(String label, Bitmap icon) {
- this(label, icon != null ? Icon.createWithBitmap(icon) : null, 0, 0, 0, 0, false, false,
- RESIZE_MODE_RESIZEABLE, -1, -1, 0);
+ this(label, icon != null ? Icon.createWithBitmap(icon) : null, 0, 0, 0, 0, 0, false,
+ false, RESIZE_MODE_RESIZEABLE, -1, -1, 0);
}
/** @hide */
public TaskDescription(@Nullable String label, @Nullable Icon icon,
int colorPrimary, int colorBackground,
int statusBarColor, int navigationBarColor,
+ @Appearance int statusBarAppearance,
boolean ensureStatusBarContrastWhenTransparent,
boolean ensureNavigationBarContrastWhenTransparent, int resizeMode, int minWidth,
int minHeight, int colorBackgroundFloating) {
@@ -1761,6 +1765,7 @@ public class ActivityManager {
mColorBackground = colorBackground;
mStatusBarColor = statusBarColor;
mNavigationBarColor = navigationBarColor;
+ mStatusBarAppearance = statusBarAppearance;
mEnsureStatusBarContrastWhenTransparent = ensureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
ensureNavigationBarContrastWhenTransparent;
@@ -1789,6 +1794,7 @@ public class ActivityManager {
mColorBackground = other.mColorBackground;
mStatusBarColor = other.mStatusBarColor;
mNavigationBarColor = other.mNavigationBarColor;
+ mStatusBarAppearance = other.mStatusBarAppearance;
mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
other.mEnsureNavigationBarContrastWhenTransparent;
@@ -1818,6 +1824,9 @@ public class ActivityManager {
if (other.mNavigationBarColor != 0) {
mNavigationBarColor = other.mNavigationBarColor;
}
+ if (other.mStatusBarAppearance != 0) {
+ mStatusBarAppearance = other.mStatusBarAppearance;
+ }
mEnsureStatusBarContrastWhenTransparent = other.mEnsureStatusBarContrastWhenTransparent;
mEnsureNavigationBarContrastWhenTransparent =
@@ -2089,6 +2098,14 @@ public class ActivityManager {
/**
* @hide
*/
+ @Appearance
+ public int getStatusBarAppearance() {
+ return mStatusBarAppearance;
+ }
+
+ /**
+ * @hide
+ */
public void setEnsureStatusBarContrastWhenTransparent(
boolean ensureStatusBarContrastWhenTransparent) {
mEnsureStatusBarContrastWhenTransparent = ensureStatusBarContrastWhenTransparent;
@@ -2097,6 +2114,13 @@ public class ActivityManager {
/**
* @hide
*/
+ public void setStatusBarAppearance(@Appearance int statusBarAppearance) {
+ mStatusBarAppearance = statusBarAppearance;
+ }
+
+ /**
+ * @hide
+ */
public boolean getEnsureNavigationBarContrastWhenTransparent() {
return mEnsureNavigationBarContrastWhenTransparent;
}
@@ -2218,6 +2242,7 @@ public class ActivityManager {
dest.writeInt(mColorBackground);
dest.writeInt(mStatusBarColor);
dest.writeInt(mNavigationBarColor);
+ dest.writeInt(mStatusBarAppearance);
dest.writeBoolean(mEnsureStatusBarContrastWhenTransparent);
dest.writeBoolean(mEnsureNavigationBarContrastWhenTransparent);
dest.writeInt(mResizeMode);
@@ -2241,6 +2266,7 @@ public class ActivityManager {
mColorBackground = source.readInt();
mStatusBarColor = source.readInt();
mNavigationBarColor = source.readInt();
+ mStatusBarAppearance = source.readInt();
mEnsureStatusBarContrastWhenTransparent = source.readBoolean();
mEnsureNavigationBarContrastWhenTransparent = source.readBoolean();
mResizeMode = source.readInt();
@@ -2289,6 +2315,7 @@ public class ActivityManager {
&& mColorBackground == other.mColorBackground
&& mStatusBarColor == other.mStatusBarColor
&& mNavigationBarColor == other.mNavigationBarColor
+ && mStatusBarAppearance == other.mStatusBarAppearance
&& mEnsureStatusBarContrastWhenTransparent
== other.mEnsureStatusBarContrastWhenTransparent
&& mEnsureNavigationBarContrastWhenTransparent
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ba5a9f741756..ccd83f756730 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -65,11 +65,9 @@ import android.os.UserManager;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.Log;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.Pools;
-import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -182,8 +180,6 @@ import java.util.function.Supplier;
*/
@SystemService(Context.APP_OPS_SERVICE)
public class AppOpsManager {
- private static final String LOG_TAG = "AppOpsManager";
-
/**
* This is a subtle behavior change to {@link #startWatchingMode}.
*
@@ -7542,7 +7538,6 @@ public class AppOpsManager {
*/
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setUidMode(int code, int uid, @Mode int mode) {
- logAnySeriousModeChanges(code, uid, null, mode);
try {
mService.setUidMode(code, uid, mode);
} catch (RemoteException e) {
@@ -7563,7 +7558,6 @@ public class AppOpsManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) {
- logAnySeriousModeChanges(strOpToOp(appOp), uid, null, mode);
try {
mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
} catch (RemoteException e) {
@@ -7599,32 +7593,11 @@ public class AppOpsManager {
}
}
- private void logAnySeriousModeChanges(int code, int uid, String packageName, @Mode int mode) {
- // TODO (b/280869337): Remove this once we have the required data.
- if (code != OP_RUN_ANY_IN_BACKGROUND || mode == MODE_ALLOWED) {
- return;
- }
- final StringBuilder log = new StringBuilder("Attempt to change RUN_ANY_IN_BACKGROUND to ")
- .append(modeToName(mode))
- .append(" for uid: ")
- .append(UserHandle.formatUid(uid))
- .append(" package: ")
- .append(packageName)
- .append(" by: ")
- .append(mContext.getOpPackageName());
- if (Process.myUid() == Process.SYSTEM_UID) {
- Slog.wtfStack(LOG_TAG, log.toString());
- } else {
- Log.w(LOG_TAG, log.toString());
- }
- }
-
/** @hide */
@UnsupportedAppUsage
@TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setMode(int code, int uid, String packageName, @Mode int mode) {
- logAnySeriousModeChanges(code, uid, packageName, mode);
try {
mService.setMode(code, uid, packageName, mode);
} catch (RemoteException e) {
@@ -7647,7 +7620,6 @@ public class AppOpsManager {
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
public void setMode(@NonNull String op, int uid, @Nullable String packageName,
@Mode int mode) {
- logAnySeriousModeChanges(strOpToOp(op), uid, packageName, mode);
try {
mService.setMode(strOpToOp(op), uid, packageName, mode);
} catch (RemoteException e) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5c1b3ee0134b..8d2394b20438 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2833,13 +2833,19 @@ public class Notification implements Parcelable
}
/**
- * Note all {@link Uri} that are referenced internally, with the expectation
- * that Uri permission grants will need to be issued to ensure the recipient
- * of this object is able to render its contents.
- *
- * @hide
- */
+ * Note all {@link Uri} that are referenced internally, with the expectation that Uri permission
+ * grants will need to be issued to ensure the recipient of this object is able to render its
+ * contents.
+ * See b/281044385 for more context and examples about what happens when this isn't done
+ * correctly.
+ *
+ * @hide
+ */
public void visitUris(@NonNull Consumer<Uri> visitor) {
+ if (publicVersion != null) {
+ publicVersion.visitUris(visitor);
+ }
+
visitor.accept(sound);
if (tickerView != null) tickerView.visitUris(visitor);
@@ -2878,13 +2884,13 @@ public class Notification implements Parcelable
ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class);
if (people != null && !people.isEmpty()) {
for (Person p : people) {
- visitor.accept(p.getIconUri());
+ p.visitUris(visitor);
}
}
final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
if (person != null) {
- visitor.accept(person.getIconUri());
+ person.visitUris(visitor);
}
final RemoteInputHistoryItem[] history = extras.getParcelableArray(
@@ -2906,12 +2912,7 @@ public class Notification implements Parcelable
if (!ArrayUtils.isEmpty(messages)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(messages)) {
- visitor.accept(message.getDataUri());
-
- Person senderPerson = message.getSenderPerson();
- if (senderPerson != null) {
- visitor.accept(senderPerson.getIconUri());
- }
+ message.visitUris(visitor);
}
}
@@ -2920,12 +2921,7 @@ public class Notification implements Parcelable
if (!ArrayUtils.isEmpty(historic)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(historic)) {
- visitor.accept(message.getDataUri());
-
- Person senderPerson = message.getSenderPerson();
- if (senderPerson != null) {
- visitor.accept(senderPerson.getIconUri());
- }
+ message.visitUris(visitor);
}
}
@@ -2935,7 +2931,7 @@ public class Notification implements Parcelable
if (isStyle(CallStyle.class) & extras != null) {
Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
if (callPerson != null) {
- visitor.accept(callPerson.getIconUri());
+ callPerson.visitUris(visitor);
}
visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
}
@@ -8829,6 +8825,18 @@ public class Notification implements Parcelable
}
/**
+ * See {@link Notification#visitUris(Consumer)}.
+ *
+ * @hide
+ */
+ public void visitUris(@NonNull Consumer<Uri> visitor) {
+ visitor.accept(getDataUri());
+ if (mSender != null) {
+ mSender.visitUris(visitor);
+ }
+ }
+
+ /**
* Returns a list of messages read from the given bundle list, e.g.
* {@link #EXTRA_MESSAGES} or {@link #EXTRA_HISTORIC_MESSAGES}.
*/
diff --git a/core/java/android/app/Person.java b/core/java/android/app/Person.java
index 97a794d4e4ea..18fc0ce6af15 100644
--- a/core/java/android/app/Person.java
+++ b/core/java/android/app/Person.java
@@ -24,6 +24,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
+import java.util.function.Consumer;
/**
* Provides an immutable reference to an entity that appears repeatedly on different surfaces of the
@@ -177,6 +178,19 @@ public final class Person implements Parcelable {
dest.writeBoolean(mIsBot);
}
+ /**
+ * Note all {@link Uri} that are referenced internally, with the expectation that Uri permission
+ * grants will need to be issued to ensure the recipient of this object is able to render its
+ * contents.
+ * See b/281044385 for more context and examples about what happens when this isn't done
+ * correctly.
+ *
+ * @hide
+ */
+ public void visitUris(@NonNull Consumer<Uri> visitor) {
+ visitor.accept(getIconUri());
+ }
+
/** Builder for the immutable {@link Person} class. */
public static class Builder {
@Nullable private CharSequence mName;
diff --git a/core/java/android/app/ServiceStartArgs.java b/core/java/android/app/ServiceStartArgs.java
index 0b000af56400..9c52367392a5 100644
--- a/core/java/android/app/ServiceStartArgs.java
+++ b/core/java/android/app/ServiceStartArgs.java
@@ -49,7 +49,7 @@ public class ServiceStartArgs implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeInt(taskRemoved ? 1 : 0);
out.writeInt(startId);
- out.writeInt(flags);
+ out.writeInt(this.flags);
if (args != null) {
out.writeInt(1);
args.writeToParcel(out, 0);
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 776e34bb4792..385fd509757b 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -24,9 +24,11 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UserIdInt;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
+import android.compat.annotation.LoggingOnly;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -49,6 +51,7 @@ import android.util.Slog;
import android.view.KeyEvent;
import android.view.View;
+import com.android.internal.compat.IPlatformCompat;
import com.android.internal.statusbar.AppClipsServiceConnector;
import com.android.internal.statusbar.IAddTileResultCallback;
import com.android.internal.statusbar.IStatusBarService;
@@ -170,6 +173,8 @@ public class StatusBarManager {
public @interface Disable2Flags {}
// LINT.ThenChange(frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/DisableFlagsLogger.kt)
+ private static final String TAG = "StatusBarManager";
+
/**
* Default disable flags for setup
*
@@ -572,13 +577,13 @@ public class StatusBarManager {
private static final long MEDIA_CONTROL_SESSION_ACTIONS = 203800354L;
/**
- * Media controls based on {@link android.app.Notification.MediaStyle} notifications will be
- * required to include a non-empty title, either in the {@link android.media.MediaMetadata} or
+ * Media controls based on {@link android.app.Notification.MediaStyle} notifications should
+ * include a non-empty title, either in the {@link android.media.MediaMetadata} or
* notification title.
*/
@ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
- private static final long MEDIA_CONTROL_REQUIRES_TITLE = 274775190L;
+ @LoggingOnly
+ private static final long MEDIA_CONTROL_BLANK_TITLE = 274775190L;
@UnsupportedAppUsage
private Context mContext;
@@ -586,6 +591,9 @@ public class StatusBarManager {
@UnsupportedAppUsage
private IBinder mToken = new Binder();
+ private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
+ ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
@UnsupportedAppUsage
StatusBarManager(Context context) {
mContext = context;
@@ -597,7 +605,7 @@ public class StatusBarManager {
mService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
if (mService == null) {
- Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+ Slog.w(TAG, "warning: no STATUS_BAR_SERVICE");
}
}
return mService;
@@ -1226,18 +1234,22 @@ public class StatusBarManager {
}
/**
- * Checks whether the given package must include a non-empty title for its media controls.
+ * Log that the given package has posted media controls with a blank title
*
* @param packageName App posting media controls
- * @param user Current user handle
- * @return true if the app is required to provide a non-empty title
+ * @param userId Current user ID
+ * @throws RuntimeException if there is an error reporting the change
*
* @hide
*/
- @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
- android.Manifest.permission.LOG_COMPAT_CHANGE})
- public static boolean isMediaTitleRequiredForApp(String packageName, UserHandle user) {
- return CompatChanges.isChangeEnabled(MEDIA_CONTROL_REQUIRES_TITLE, packageName, user);
+ public void logBlankMediaTitle(String packageName, @UserIdInt int userId)
+ throws RuntimeException {
+ try {
+ mPlatformCompat.reportChangeByPackageName(MEDIA_CONTROL_BLANK_TITLE, packageName,
+ userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index 99d406446dae..b29e73a717f4 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -292,12 +292,12 @@ public final class WallpaperInfo implements Parcelable {
packageName = mService.serviceInfo.packageName;
applicationInfo = mService.serviceInfo.applicationInfo;
}
- String contextUriString = pm.getText(
- packageName, mContextUriResource, applicationInfo).toString();
- if (contextUriString == null) {
+ CharSequence contextUriCharSequence = pm.getText(
+ packageName, mContextUriResource, applicationInfo);
+ if (contextUriCharSequence == null) {
return null;
}
- return Uri.parse(contextUriString);
+ return Uri.parse(contextUriCharSequence.toString());
}
/**
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 57935e3bd5b1..cfca7cbb0a9a 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -853,7 +853,7 @@ public class WallpaperManager {
private static boolean isLockscreenLiveWallpaperEnabledHelper() {
if (sGlobals == null) {
sIsLockscreenLiveWallpaperEnabled = SystemProperties.getBoolean(
- "persist.wm.debug.lockscreen_live_wallpaper", false);
+ "persist.wm.debug.lockscreen_live_wallpaper", true);
}
if (sIsLockscreenLiveWallpaperEnabled == null) {
try {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 783e7d3e2afc..b2a923043dbe 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -581,6 +581,7 @@ public class DevicePolicyManager {
* <li>{@link #LOCK_TASK_FEATURE_HOME}</li>
* <li>{@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS}</li>
* <li>{@link #LOCK_TASK_FEATURE_NOTIFICATIONS}</li>
+ * <li>{@link #LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK}</li>
* </ul>
* <li>{@link #getLockTaskFeatures(ComponentName)}</li>
* <li>{@link #setLockTaskPackages(ComponentName, String[])}</li>
diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java
index 856bde870bcf..36e0529e3566 100644
--- a/core/java/android/content/ContentCaptureOptions.java
+++ b/core/java/android/content/ContentCaptureOptions.java
@@ -76,6 +76,20 @@ public final class ContentCaptureOptions implements Parcelable {
public final boolean disableFlushForViewTreeAppearing;
/**
+ * Is the content capture receiver enabled.
+ *
+ * @hide
+ */
+ public final boolean enableReceiver;
+
+ /**
+ * Options for the content protection flow.
+ *
+ * @hide
+ */
+ @NonNull public final ContentProtectionOptions contentProtectionOptions;
+
+ /**
* List of activities explicitly allowlisted for content capture (or {@code null} if allowlisted
* for all acitivites in the package).
*/
@@ -94,52 +108,99 @@ public final class ContentCaptureOptions implements Parcelable {
* for contexts belonging to the content capture service app.
*/
public ContentCaptureOptions(int loggingLevel) {
- this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0,
- /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0,
- /* logHistorySize= */ 0, /* disableFlushForViewTreeAppearing= */ false,
+ this(
+ /* lite= */ true,
+ loggingLevel,
+ /* maxBufferSize= */ 0,
+ /* idleFlushingFrequencyMs= */ 0,
+ /* textChangeFlushingFrequencyMs= */ 0,
+ /* logHistorySize= */ 0,
+ /* disableFlushForViewTreeAppearing= */ false,
+ /* enableReceiver= */ false,
+ new ContentProtectionOptions(
+ /* enableReceiver= */ false,
+ /* bufferSize= */ 0),
/* whitelistedComponents= */ null);
}
- /**
- * Default constructor.
- */
- public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs,
- int textChangeFlushingFrequencyMs, int logHistorySize,
- @SuppressLint({"ConcreteCollection", "NullableCollection"})
- @Nullable ArraySet<ComponentName> whitelistedComponents) {
- this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs,
- textChangeFlushingFrequencyMs, logHistorySize,
+ /** Default constructor. */
+ public ContentCaptureOptions(
+ int loggingLevel,
+ int maxBufferSize,
+ int idleFlushingFrequencyMs,
+ int textChangeFlushingFrequencyMs,
+ int logHistorySize,
+ @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable
+ ArraySet<ComponentName> whitelistedComponents) {
+ this(
+ /* lite= */ false,
+ loggingLevel,
+ maxBufferSize,
+ idleFlushingFrequencyMs,
+ textChangeFlushingFrequencyMs,
+ logHistorySize,
ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING,
+ ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER,
+ new ContentProtectionOptions(
+ ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER,
+ ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE),
whitelistedComponents);
}
/** @hide */
- public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs,
- int textChangeFlushingFrequencyMs, int logHistorySize,
+ public ContentCaptureOptions(
+ int loggingLevel,
+ int maxBufferSize,
+ int idleFlushingFrequencyMs,
+ int textChangeFlushingFrequencyMs,
+ int logHistorySize,
boolean disableFlushForViewTreeAppearing,
- @SuppressLint({"ConcreteCollection", "NullableCollection"})
- @Nullable ArraySet<ComponentName> whitelistedComponents) {
- this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs,
- textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing,
+ boolean enableReceiver,
+ @NonNull ContentProtectionOptions contentProtectionOptions,
+ @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable
+ ArraySet<ComponentName> whitelistedComponents) {
+ this(
+ /* lite= */ false,
+ loggingLevel,
+ maxBufferSize,
+ idleFlushingFrequencyMs,
+ textChangeFlushingFrequencyMs,
+ logHistorySize,
+ disableFlushForViewTreeAppearing,
+ enableReceiver,
+ contentProtectionOptions,
whitelistedComponents);
}
/** @hide */
@VisibleForTesting
public ContentCaptureOptions(@Nullable ArraySet<ComponentName> whitelistedComponents) {
- this(ContentCaptureManager.LOGGING_LEVEL_VERBOSE,
+ this(
+ ContentCaptureManager.LOGGING_LEVEL_VERBOSE,
ContentCaptureManager.DEFAULT_MAX_BUFFER_SIZE,
ContentCaptureManager.DEFAULT_IDLE_FLUSHING_FREQUENCY_MS,
ContentCaptureManager.DEFAULT_TEXT_CHANGE_FLUSHING_FREQUENCY_MS,
ContentCaptureManager.DEFAULT_LOG_HISTORY_SIZE,
ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING,
+ ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER,
+ new ContentProtectionOptions(
+ ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER,
+ ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE),
whitelistedComponents);
}
- private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize,
- int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize,
+ private ContentCaptureOptions(
+ boolean lite,
+ int loggingLevel,
+ int maxBufferSize,
+ int idleFlushingFrequencyMs,
+ int textChangeFlushingFrequencyMs,
+ int logHistorySize,
boolean disableFlushForViewTreeAppearing,
- @Nullable ArraySet<ComponentName> whitelistedComponents) {
+ boolean enableReceiver,
+ @NonNull ContentProtectionOptions contentProtectionOptions,
+ @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable
+ ArraySet<ComponentName> whitelistedComponents) {
this.lite = lite;
this.loggingLevel = loggingLevel;
this.maxBufferSize = maxBufferSize;
@@ -147,6 +208,8 @@ public final class ContentCaptureOptions implements Parcelable {
this.textChangeFlushingFrequencyMs = textChangeFlushingFrequencyMs;
this.logHistorySize = logHistorySize;
this.disableFlushForViewTreeAppearing = disableFlushForViewTreeAppearing;
+ this.enableReceiver = enableReceiver;
+ this.contentProtectionOptions = contentProtectionOptions;
this.whitelistedComponents = whitelistedComponents;
}
@@ -191,12 +254,22 @@ public final class ContentCaptureOptions implements Parcelable {
return "ContentCaptureOptions [loggingLevel=" + loggingLevel + " (lite)]";
}
final StringBuilder string = new StringBuilder("ContentCaptureOptions [");
- string.append("loggingLevel=").append(loggingLevel)
- .append(", maxBufferSize=").append(maxBufferSize)
- .append(", idleFlushingFrequencyMs=").append(idleFlushingFrequencyMs)
- .append(", textChangeFlushingFrequencyMs=").append(textChangeFlushingFrequencyMs)
- .append(", logHistorySize=").append(logHistorySize)
- .append(", disableFlushForViewTreeAppearing=").append(disableFlushForViewTreeAppearing);
+ string.append("loggingLevel=")
+ .append(loggingLevel)
+ .append(", maxBufferSize=")
+ .append(maxBufferSize)
+ .append(", idleFlushingFrequencyMs=")
+ .append(idleFlushingFrequencyMs)
+ .append(", textChangeFlushingFrequencyMs=")
+ .append(textChangeFlushingFrequencyMs)
+ .append(", logHistorySize=")
+ .append(logHistorySize)
+ .append(", disableFlushForViewTreeAppearing=")
+ .append(disableFlushForViewTreeAppearing)
+ .append(", enableReceiver=")
+ .append(enableReceiver)
+ .append(", contentProtectionOptions=")
+ .append(contentProtectionOptions);
if (whitelistedComponents != null) {
string.append(", whitelisted=").append(whitelistedComponents);
}
@@ -210,11 +283,21 @@ public final class ContentCaptureOptions implements Parcelable {
pw.print(", lite");
return;
}
- pw.print(", bufferSize="); pw.print(maxBufferSize);
- pw.print(", idle="); pw.print(idleFlushingFrequencyMs);
- pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs);
- pw.print(", logSize="); pw.print(logHistorySize);
- pw.print(", disableFlushForViewTreeAppearing="); pw.print(disableFlushForViewTreeAppearing);
+ pw.print(", bufferSize=");
+ pw.print(maxBufferSize);
+ pw.print(", idle=");
+ pw.print(idleFlushingFrequencyMs);
+ pw.print(", textIdle=");
+ pw.print(textChangeFlushingFrequencyMs);
+ pw.print(", logSize=");
+ pw.print(logHistorySize);
+ pw.print(", disableFlushForViewTreeAppearing=");
+ pw.print(disableFlushForViewTreeAppearing);
+ pw.print(", enableReceiver=");
+ pw.print(enableReceiver);
+ pw.print(", contentProtectionOptions=[");
+ contentProtectionOptions.dumpShort(pw);
+ pw.print("]");
if (whitelistedComponents != null) {
pw.print(", whitelisted="); pw.print(whitelistedComponents);
}
@@ -236,6 +319,8 @@ public final class ContentCaptureOptions implements Parcelable {
parcel.writeInt(textChangeFlushingFrequencyMs);
parcel.writeInt(logHistorySize);
parcel.writeBoolean(disableFlushForViewTreeAppearing);
+ parcel.writeBoolean(enableReceiver);
+ contentProtectionOptions.writeToParcel(parcel);
parcel.writeArraySet(whitelistedComponents);
}
@@ -254,12 +339,22 @@ public final class ContentCaptureOptions implements Parcelable {
final int textChangeFlushingFrequencyMs = parcel.readInt();
final int logHistorySize = parcel.readInt();
final boolean disableFlushForViewTreeAppearing = parcel.readBoolean();
+ final boolean enableReceiver = parcel.readBoolean();
+ final ContentProtectionOptions contentProtectionOptions =
+ ContentProtectionOptions.createFromParcel(parcel);
@SuppressWarnings("unchecked")
final ArraySet<ComponentName> whitelistedComponents =
(ArraySet<ComponentName>) parcel.readArraySet(null);
- return new ContentCaptureOptions(loggingLevel, maxBufferSize,
- idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize,
- disableFlushForViewTreeAppearing, whitelistedComponents);
+ return new ContentCaptureOptions(
+ loggingLevel,
+ maxBufferSize,
+ idleFlushingFrequencyMs,
+ textChangeFlushingFrequencyMs,
+ logHistorySize,
+ disableFlushForViewTreeAppearing,
+ enableReceiver,
+ contentProtectionOptions,
+ whitelistedComponents);
}
@Override
@@ -267,4 +362,62 @@ public final class ContentCaptureOptions implements Parcelable {
return new ContentCaptureOptions[size];
}
};
+
+ /**
+ * Content protection options for a given package.
+ *
+ * <p>Does not implement {@code Parcelable} since it is an inner class without a matching AIDL.
+ *
+ * @hide
+ */
+ public static class ContentProtectionOptions {
+
+ /**
+ * Is the content protection receiver enabled.
+ *
+ * @hide
+ */
+ public final boolean enableReceiver;
+
+ /**
+ * Size of the in-memory ring buffer for the content protection flow.
+ *
+ * @hide
+ */
+ public final int bufferSize;
+
+ public ContentProtectionOptions(boolean enableReceiver, int bufferSize) {
+ this.enableReceiver = enableReceiver;
+ this.bufferSize = bufferSize;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder("ContentProtectionOptions [");
+ stringBuilder
+ .append("enableReceiver=")
+ .append(enableReceiver)
+ .append(", bufferSize=")
+ .append(bufferSize);
+ return stringBuilder.append(']').toString();
+ }
+
+ private void dumpShort(@NonNull PrintWriter pw) {
+ pw.print("enableReceiver=");
+ pw.print(enableReceiver);
+ pw.print(", bufferSize=");
+ pw.print(bufferSize);
+ }
+
+ private void writeToParcel(Parcel parcel) {
+ parcel.writeBoolean(enableReceiver);
+ parcel.writeInt(bufferSize);
+ }
+
+ private static ContentProtectionOptions createFromParcel(Parcel parcel) {
+ boolean enableReceiver = parcel.readBoolean();
+ int bufferSize = parcel.readInt();
+ return new ContentProtectionOptions(enableReceiver, bufferSize);
+ }
+ }
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 96118f6c43ea..105b38a40825 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -444,6 +444,10 @@ public class PackageInstaller {
* exist, it may be missing native code for the ABIs supported by the
* device, or it requires a newer SDK version, etc.
*
+ * Starting in {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, an app with only 32-bit native
+ * code can still be installed on a device that supports both 64-bit and 32-bit ABIs.
+ * However, a warning dialog will be displayed when the app is launched.
+ *
* @see #EXTRA_STATUS_MESSAGE
*/
public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index b6012757c35d..3ffbe1d1c71b 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -1,223 +1,170 @@
{
- "imports": [
- {
- "path": "frameworks/base/core/tests/coretests/src/android/content/pm"
- },
- {
- "path": "frameworks/base/services/tests/PackageManagerServiceTests"
- },
- {
- "path": "frameworks/base/services/tests/PackageManager"
- },
- {
- "path": "frameworks/base/services/tests/PackageManagerComponentOverrideTests"
- },
- {
- "path": "frameworks/base/services/tests/servicestests/src/com/android/server/pm"
- },
- {
- "path": "cts/tests/tests/packageinstaller"
- },
- {
- "path": "cts/hostsidetests/stagedinstall"
- },
- {
- "path": "cts/hostsidetests/packagemanager"
- },
- {
- "path": "cts/hostsidetests/os/test_mappings/packagemanager"
- },
- {
- "path": "cts/hostsidetests/appsearch"
- },
- {
- "path": "system/apex/tests"
- },
- {
- "path": "cts/tests/tests/content/pm/SecureFrp"
- }
- ],
- "presubmit": [
- {
- "name": "CtsInstantAppTests",
- "file_patterns": ["(/|^)InstantApp[^/]*"]
- },
- {
- "name": "CarrierAppIntegrationTestCases"
- },
- {
- "name": "ApkVerityTest"
- },
- {
- "name": "CtsSilentUpdateHostTestCases"
- },
- {
- "name": "CtsSuspendAppsTestCases"
- },
- {
- "name": "CtsAppFgsTestCases",
- "file_patterns": ["(/|^)ServiceInfo[^/]*"],
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.LargeTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
- "name": "CtsShortFgsTestCases",
- "file_patterns": ["(/|^)ServiceInfo[^/]*"],
- "options": [
+ "imports":[
{
- "include-annotation": "android.platform.test.annotations.Presubmit"
+ "path":"frameworks/base/core/tests/coretests/src/android/content/pm"
},
{
- "exclude-annotation": "androidx.test.filters.LargeTest"
+ "path":"frameworks/base/services/tests/PackageManagerServiceTests"
},
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
- "name": "CtsIncrementalInstallHostTestCases",
- "options": [
+ "path":"frameworks/base/services/tests/PackageManager"
+ },
{
- "include-filter": "android.incrementalinstall.cts.IncrementalFeatureTest"
- }
- ]
- }
- ],
- "presubmit-large": [
- {
- "name": "CtsContentTestCases",
- "options": [
+ "path":"frameworks/base/services/tests/PackageManagerComponentOverrideTests"
+ },
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
+ "path":"frameworks/base/services/tests/servicestests/src/com/android/server/pm"
},
{
- "exclude-annotation": "org.junit.Ignore"
+ "path":"cts/tests/tests/packageinstaller"
},
{
- "include-filter": "android.content.pm.cts"
- }
- ]
- },
- {
- "name": "CtsUsesNativeLibraryTest",
- "options": [
+ "path":"cts/hostsidetests/stagedinstall"
+ },
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
+ "path":"cts/hostsidetests/packagemanager"
},
{
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- },
- {
- "name": "CtsSuspendAppsPermissionTestCases",
- "options": [
+ "path":"cts/hostsidetests/os/test_mappings/packagemanager"
+ },
+ {
+ "path":"cts/hostsidetests/appsearch"
+ },
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
+ "path":"system/apex/tests"
},
{
- "exclude-annotation": "org.junit.Ignore"
+ "path":"cts/tests/tests/content/pm/SecureFrp"
}
- ]
- },
- {
- "name": "CtsAppSecurityHostTestCases",
- "options": [
+ ],
+ "presubmit":[
{
- "include-annotation": "android.platform.test.annotations.Presubmit"
+ "name":"CtsInstantAppTests",
+ "file_patterns":[
+ "(/|^)InstantApp[^/]*"
+ ]
},
{
- "exclude-annotation": "android.platform.test.annotations.Postsubmit"
+ "name":"CarrierAppIntegrationTestCases"
},
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
+ "name":"ApkVerityTest"
},
{
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
- ],
- "postsubmit": [
- {
- "name": "CtsAppSecurityHostTestCases",
- "options": [
- {
- "include-filter": "android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
+ "name":"CtsSilentUpdateHostTestCases"
+ },
+ {
+ "name":"CtsSuspendAppsTestCases"
+ },
+ {
+ "name":"CtsAppFgsTestCases",
+ "file_patterns":[
+ "(/|^)ServiceInfo[^/]*"
+ ],
+ "options":[
+ {
+ "include-annotation":"android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation":"androidx.test.filters.LargeTest"
+ },
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name":"CtsShortFgsTestCases",
+ "file_patterns":[
+ "(/|^)ServiceInfo[^/]*"
+ ],
+ "options":[
+ {
+ "include-annotation":"android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation":"androidx.test.filters.LargeTest"
+ },
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name":"CtsIncrementalInstallHostTestCases",
+ "options":[
+ {
+ "include-filter":"android.incrementalinstall.cts.IncrementalFeatureTest"
+ }
+ ]
}
- ]
- },
- {
- "name": "CtsInstallHostTestCases"
- }
- ],
- "staged-platinum-postsubmit": [
- {
- "name": "CtsIncrementalInstallHostTestCases"
- },
- {
- "name": "CtsAppSecurityHostTestCases",
- "options": [
- {
- "include-filter": "android.appsecurity.cts.SplitTests"
- },
- {
- "include-filter": "android.appsecurity.cts.EphemeralTest"
+ ],
+ "presubmit-large":[
+ {
+ "name":"CtsContentTestCases",
+ "options":[
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ },
+ {
+ "include-filter":"android.content.pm.cts"
+ }
+ ]
+ },
+ {
+ "name":"CtsUsesNativeLibraryTest",
+ "options":[
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ }
+ ]
+ },
+ {
+ "name":"CtsSuspendAppsPermissionTestCases",
+ "options":[
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ }
+ ]
+ },
+ {
+ "name":"CtsAppSecurityHostTestCases",
+ "options":[
+ {
+ "include-annotation":"android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation":"android.platform.test.annotations.Postsubmit"
+ },
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ }
+ ]
}
- ]
- },
- {
- "name": "CtsContentTestCases",
- "options": [
+ ],
+ "postsubmit":[
+ {
+ "name":"CtsAppSecurityHostTestCases",
+ "options":[
+ {
+ "include-filter":"android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
+ }
+ ]
+ },
{
- "include-filter": "android.content.cts.IntentFilterTest"
+ "name":"CtsInstallHostTestCases"
}
- ]
- }
- ],
- "platinum-postsubmit": [
- {
- "name": "CtsIncrementalInstallHostTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
- "name": "CtsAppSecurityHostTestCases",
- "options": [
- {
- "include-filter": "android.appsecurity.cts.SplitTests"
- },
- {
- "include-filter": "android.appsecurity.cts.EphemeralTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
- "name": "CtsContentTestCases",
- "options":[
- {
- "include-filter": "android.content.cts.IntentFilterTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- }
- ]
-}
+ ]
+} \ No newline at end of file
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index e23bbc6c347d..d3bde4b4b8a8 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -20,6 +20,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainRunna
import android.annotation.NonNull;
import android.content.Context;
+import android.graphics.ImageFormat;
import android.hardware.ICameraService;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
@@ -1478,6 +1479,12 @@ public class CameraDeviceImpl extends CameraDevice
}
}
+ // Allow RAW formats, even when not advertised.
+ if (inputFormat == ImageFormat.RAW_PRIVATE || inputFormat == ImageFormat.RAW10
+ || inputFormat == ImageFormat.RAW12 || inputFormat == ImageFormat.RAW_SENSOR) {
+ return true;
+ }
+
if (validFormat == false) {
return false;
}
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 17bbe1459d03..33960c058baa 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -266,7 +266,7 @@ public class InputSettings {
*/
public static boolean useTouchpadTapToClick(@NonNull Context context) {
return Settings.System.getIntForUser(context.getContentResolver(),
- Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT) == 1;
+ Settings.System.TOUCHPAD_TAP_TO_CLICK, 1, UserHandle.USER_CURRENT) == 1;
}
/**
diff --git a/core/java/android/hardware/lights/Light.java b/core/java/android/hardware/lights/Light.java
index 1df9b75f0b09..18d0b09faa14 100644
--- a/core/java/android/hardware/lights/Light.java
+++ b/core/java/android/hardware/lights/Light.java
@@ -110,6 +110,8 @@ public final class Light implements Parcelable {
private final int mOrdinal;
private final int mType;
private final int mCapabilities;
+ @Nullable
+ private final int[] mPreferredBrightnessLevels;
/**
* Creates a new light with the given data.
@@ -117,7 +119,7 @@ public final class Light implements Parcelable {
* @hide
*/
public Light(int id, int ordinal, int type) {
- this(id, "Light", ordinal, type, 0);
+ this(id, "Light", ordinal, type, 0, null);
}
/**
@@ -126,11 +128,22 @@ public final class Light implements Parcelable {
* @hide
*/
public Light(int id, String name, int ordinal, int type, int capabilities) {
+ this(id, name, ordinal, type, capabilities, null);
+ }
+
+ /**
+ * Creates a new light with the given data.
+ *
+ * @hide
+ */
+ public Light(int id, String name, int ordinal, int type, int capabilities,
+ @Nullable int[] preferredBrightnessLevels) {
mId = id;
mName = name;
mOrdinal = ordinal;
mType = type;
mCapabilities = capabilities;
+ mPreferredBrightnessLevels = preferredBrightnessLevels;
}
private Light(@NonNull Parcel in) {
@@ -139,6 +152,7 @@ public final class Light implements Parcelable {
mOrdinal = in.readInt();
mType = in.readInt();
mCapabilities = in.readInt();
+ mPreferredBrightnessLevels = in.createIntArray();
}
/** Implement the Parcelable interface */
@@ -149,6 +163,7 @@ public final class Light implements Parcelable {
dest.writeInt(mOrdinal);
dest.writeInt(mType);
dest.writeInt(mCapabilities);
+ dest.writeIntArray(mPreferredBrightnessLevels);
}
/** Implement the Parcelable interface */
@@ -252,4 +267,17 @@ public final class Light implements Parcelable {
return (mCapabilities & LIGHT_CAPABILITY_COLOR_RGB) == LIGHT_CAPABILITY_COLOR_RGB;
}
+ /**
+ * Returns preferred brightness levels for the light which will be used when user
+ * increase/decrease brightness levels for the light (currently only used for Keyboard
+ * backlight control using backlight up/down keys).
+ *
+ * The values in the preferred brightness level array are in the range [0, 255].
+ *
+ * @hide
+ */
+ @Nullable
+ public int[] getPreferredBrightnessLevels() {
+ return mPreferredBrightnessLevels;
+ }
}
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index 69105016e0ea..78388efe98c7 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -246,8 +246,7 @@ final class NavigationBarController {
@Override
public void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets,
@NonNull ViewTreeObserver.InternalInsetsInfo dest) {
- if (!mImeDrawsImeNavBar || mNavigationBarFrame == null
- || mService.isExtractViewShown()) {
+ if (!mImeDrawsImeNavBar || mNavigationBarFrame == null) {
return;
}
@@ -255,53 +254,58 @@ final class NavigationBarController {
if (systemInsets != null) {
final Window window = mService.mWindow.getWindow();
final View decor = window.getDecorView();
- Region touchableRegion = null;
- final View inputFrame = mService.mInputFrame;
- switch (originalInsets.touchableInsets) {
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
- if (inputFrame.getVisibility() == View.VISIBLE) {
- inputFrame.getLocationInWindow(mTempPos);
- mTempRect.set(mTempPos[0], mTempPos[1],
- mTempPos[0] + inputFrame.getWidth(),
- mTempPos[1] + inputFrame.getHeight());
- touchableRegion = new Region(mTempRect);
- }
- break;
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
- if (inputFrame.getVisibility() == View.VISIBLE) {
- inputFrame.getLocationInWindow(mTempPos);
- mTempRect.set(mTempPos[0], originalInsets.contentTopInsets,
- mTempPos[0] + inputFrame.getWidth() ,
- mTempPos[1] + inputFrame.getHeight());
- touchableRegion = new Region(mTempRect);
- }
- break;
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
- if (inputFrame.getVisibility() == View.VISIBLE) {
- inputFrame.getLocationInWindow(mTempPos);
- mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets,
- mTempPos[0] + inputFrame.getWidth(),
- mTempPos[1] + inputFrame.getHeight());
- touchableRegion = new Region(mTempRect);
- }
- break;
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION:
- touchableRegion = new Region();
- touchableRegion.set(originalInsets.touchableRegion);
- break;
- }
- // Hereafter "mTempRect" means a navigation bar rect.
- mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom,
- decor.getRight(), decor.getBottom());
- if (touchableRegion == null) {
- touchableRegion = new Region(mTempRect);
- } else {
- touchableRegion.union(mTempRect);
- }
- dest.touchableRegion.set(touchableRegion);
- dest.setTouchableInsets(
- ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ // If the extract view is shown, everything is touchable, so no need to update
+ // touchable insets, but we still update normal insets below.
+ if (!mService.isExtractViewShown()) {
+ Region touchableRegion = null;
+ final View inputFrame = mService.mInputFrame;
+ switch (originalInsets.touchableInsets) {
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
+ if (inputFrame.getVisibility() == View.VISIBLE) {
+ inputFrame.getLocationInWindow(mTempPos);
+ mTempRect.set(mTempPos[0], mTempPos[1],
+ mTempPos[0] + inputFrame.getWidth(),
+ mTempPos[1] + inputFrame.getHeight());
+ touchableRegion = new Region(mTempRect);
+ }
+ break;
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
+ if (inputFrame.getVisibility() == View.VISIBLE) {
+ inputFrame.getLocationInWindow(mTempPos);
+ mTempRect.set(mTempPos[0], originalInsets.contentTopInsets,
+ mTempPos[0] + inputFrame.getWidth(),
+ mTempPos[1] + inputFrame.getHeight());
+ touchableRegion = new Region(mTempRect);
+ }
+ break;
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
+ if (inputFrame.getVisibility() == View.VISIBLE) {
+ inputFrame.getLocationInWindow(mTempPos);
+ mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets,
+ mTempPos[0] + inputFrame.getWidth(),
+ mTempPos[1] + inputFrame.getHeight());
+ touchableRegion = new Region(mTempRect);
+ }
+ break;
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION:
+ touchableRegion = new Region();
+ touchableRegion.set(originalInsets.touchableRegion);
+ break;
+ }
+ // Hereafter "mTempRect" means a navigation bar rect.
+ mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom,
+ decor.getRight(), decor.getBottom());
+ if (touchableRegion == null) {
+ touchableRegion = new Region(mTempRect);
+ } else {
+ touchableRegion.union(mTempRect);
+ }
+
+ dest.touchableRegion.set(touchableRegion);
+ dest.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ }
// TODO(b/215443343): See if we can use View#OnLayoutChangeListener().
// TODO(b/215443343): See if we can replace DecorView#mNavigationColorViewState.view
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 2e64a74a5d67..ff47f3fc30aa 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -444,7 +444,7 @@ public class VpnManager {
* Retrieve the VpnProfileState for the profile provisioned by the calling package.
*
* @return the VpnProfileState with current information, or null if there was no profile
- * provisioned by the calling package.
+ * provisioned and started by the calling package.
*/
@Nullable
public VpnProfileState getProvisionedVpnProfileState() {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7d68b44581de..84f1880213b8 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -736,7 +736,7 @@ public class UserManager {
* The default value is <code>false</code>.
*
* <p>Holders of the permission
- * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MODIFY_USERS}
* can set this restriction using the DevicePolicyManager APIs mentioned below.
*
* <p>Key for user restrictions.
@@ -941,7 +941,7 @@ public class UserManager {
* this restriction will be set as a base restriction which cannot be removed by any admin.
*
* <p>Holders of the permission
- * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MODIFY_USERS}
* can set this restriction using the DevicePolicyManager APIs mentioned below.
*
* <p>Key for user restrictions.
@@ -1451,7 +1451,7 @@ public class UserManager {
* affected. The default value is <code>false</code>.
*
* <p>Holders of the permission
- * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MODIFY_USERS}
* can set this restriction using the DevicePolicyManager APIs mentioned below.
*
* <p>Key for user restrictions.
@@ -1597,7 +1597,7 @@ public class UserManager {
* set.
*
* <p>Holders of the permission
- * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MODIFY_USERS}
* can set this restriction using the DevicePolicyManager APIs mentioned below.
*
* <p>The default value is <code>false</code>.
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 737c95fadccd..f0140e1a4df2 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -88,6 +88,18 @@ public abstract class ContentCaptureService extends Service {
"android.service.contentcapture.ContentCaptureService";
/**
+ * The {@link Intent} that must be declared as handled by the protection service.
+ *
+ * <p>To be supported, the service must also require the {@link
+ * android.Manifest.permission#BIND_CONTENT_CAPTURE_SERVICE} permission so that other
+ * applications can not abuse it.
+ *
+ * @hide
+ */
+ public static final String PROTECTION_SERVICE_INTERFACE =
+ "android.service.contentcapture.ContentProtectionService";
+
+ /**
* Name under which a ContentCaptureService component publishes information about itself.
*
* <p>This meta-data should reference an XML resource containing a
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 4b761c105803..ab9ae0acc01e 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -1066,7 +1066,9 @@ public class VoiceInteractionService extends Service {
synchronized (mLock) {
mActiveDetectors.forEach(detector -> {
try {
- if (detector != mActiveVisualQueryDetector.getInitializationDelegate()
+ // Skip destroying VisualQueryDetector if HotwordDetectors are created
+ if (!(mActiveVisualQueryDetector != null
+ && detector == mActiveVisualQueryDetector.getInitializationDelegate())
|| shouldShutDownVisualQueryDetector) {
detector.destroy();
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 7f0a666da91f..4e086c2ad134 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1391,7 +1391,7 @@ public abstract class WallpaperService extends Service {
Trace.endSection();
}
- if (redrawNeeded) {
+ if (redrawNeeded || sizeChanged) {
Trace.beginSection("WPMS.Engine.onSurfaceRedrawNeeded");
onSurfaceRedrawNeeded(mSurfaceHolder);
Trace.endSection();
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index dacb25ca1628..bb5dd7f0cdfe 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -812,7 +812,7 @@ public class SpeechRecognizer {
Intent recognizerIntent,
Executor callbackExecutor,
RecognitionSupportCallback recognitionSupportCallback) {
- if (!maybeInitializeManagerService()) {
+ if (!maybeInitializeManagerService() || !checkOpenConnection()) {
return;
}
try {
@@ -831,7 +831,7 @@ public class SpeechRecognizer {
Intent recognizerIntent,
@Nullable Executor callbackExecutor,
@Nullable ModelDownloadListener modelDownloadListener) {
- if (!maybeInitializeManagerService()) {
+ if (!maybeInitializeManagerService() || !checkOpenConnection()) {
return;
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index d8bff1c4cb10..7e4e4022f00f 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -658,6 +658,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
/** Set of inset types which cannot be controlled by the user animation */
private @InsetsType int mDisabledUserAnimationInsetsTypes;
+ /** Set of inset types which are existing */
+ private @InsetsType int mExistingTypes = 0;
+
/** Set of inset types which are visible */
private @InsetsType int mVisibleTypes = WindowInsets.Type.defaultVisible();
@@ -906,6 +909,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
mVisibleTypes = visibleTypes;
}
+ if (mExistingTypes != existingTypes) {
+ if (WindowInsets.Type.hasCompatSystemBars(mExistingTypes ^ existingTypes)) {
+ mCompatSysUiVisibilityStaled = true;
+ }
+ mExistingTypes = existingTypes;
+ }
InsetsState.traverse(mState, newState, mRemoveGoneSources);
updateDisabledUserAnimationTypes(disabledUserAnimationTypes);
@@ -1365,7 +1374,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
// The requested visibilities should be delayed as well. Otherwise, we might override
// the insets visibility before playing animation.
- setRequestedVisibleTypes(mReportedRequestedVisibleTypes, typesReady);
+ setRequestedVisibleTypes(mReportedRequestedVisibleTypes, types);
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
if (!fromIme) {
@@ -1662,7 +1671,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (mCompatSysUiVisibilityStaled) {
mCompatSysUiVisibilityStaled = false;
mHost.updateCompatSysUiVisibility(
- mVisibleTypes, mRequestedVisibleTypes, mControllableTypes);
+ // Treat non-existing types as controllable types for compatibility.
+ mVisibleTypes, mRequestedVisibleTypes, mControllableTypes | ~mExistingTypes);
}
}
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 470c2801d838..a47f34f4125e 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -164,6 +164,10 @@ public class InsetsFrameProvider implements Parcelable {
return mFlags;
}
+ public boolean hasFlags(@Flags int mask) {
+ return (mFlags & mask) == mask;
+ }
+
public InsetsFrameProvider setInsetsSize(Insets insetsSize) {
mInsetsSize = insetsSize;
return this;
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index 9fc42fff7084..e10184976abe 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -58,9 +58,20 @@ public class InsetsSource implements Parcelable {
*/
public static final int FLAG_SUPPRESS_SCRIM = 1;
+ /**
+ * Controls whether the insets frame will be used to move {@link RoundedCorner} inward with the
+ * insets frame size when calculating the rounded corner insets to other windows.
+ *
+ * For example, task bar will draw fake rounded corners above itself, so we need to move the
+ * rounded corner up by the task bar insets size to make other windows see a rounded corner
+ * above the task bar.
+ */
+ public static final int FLAG_INSETS_ROUNDED_CORNER = 1 << 1;
+
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = "FLAG_", value = {
FLAG_SUPPRESS_SCRIM,
+ FLAG_INSETS_ROUNDED_CORNER,
})
public @interface Flags {}
@@ -78,7 +89,6 @@ public class InsetsSource implements Parcelable {
private @Nullable Rect mVisibleFrame;
private boolean mVisible;
- private boolean mInsetsRoundedCornerFrame;
private final Rect mTmpFrame = new Rect();
@@ -98,7 +108,6 @@ public class InsetsSource implements Parcelable {
? new Rect(other.mVisibleFrame)
: null;
mFlags = other.mFlags;
- mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
}
public void set(InsetsSource other) {
@@ -108,7 +117,6 @@ public class InsetsSource implements Parcelable {
? new Rect(other.mVisibleFrame)
: null;
mFlags = other.mFlags;
- mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
}
public InsetsSource setFrame(int left, int top, int right, int bottom) {
@@ -136,6 +144,11 @@ public class InsetsSource implements Parcelable {
return this;
}
+ public InsetsSource setFlags(@Flags int flags, @Flags int mask) {
+ mFlags = (mFlags & ~mask) | (flags & mask);
+ return this;
+ }
+
public int getId() {
return mId;
}
@@ -160,20 +173,15 @@ public class InsetsSource implements Parcelable {
return mFlags;
}
+ public boolean hasFlags(int flags) {
+ return (mFlags & flags) == flags;
+ }
+
boolean isUserControllable() {
// If mVisibleFrame is null, it will be the same area as mFrame.
return mVisibleFrame == null || !mVisibleFrame.isEmpty();
}
- public boolean insetsRoundedCornerFrame() {
- return mInsetsRoundedCornerFrame;
- }
-
- public InsetsSource setInsetsRoundedCornerFrame(boolean insetsRoundedCornerFrame) {
- mInsetsRoundedCornerFrame = insetsRoundedCornerFrame;
- return this;
- }
-
/**
* Calculates the insets this source will cause to a client window.
*
@@ -317,6 +325,9 @@ public class InsetsSource implements Parcelable {
if ((flags & FLAG_SUPPRESS_SCRIM) != 0) {
joiner.add("SUPPRESS_SCRIM");
}
+ if ((flags & FLAG_INSETS_ROUNDED_CORNER) != 0) {
+ joiner.add("INSETS_ROUNDED_CORNER");
+ }
return joiner.toString();
}
@@ -347,7 +358,6 @@ public class InsetsSource implements Parcelable {
}
pw.print(" visible="); pw.print(mVisible);
pw.print(" flags="); pw.print(flagsToString(mFlags));
- pw.print(" insetsRoundedCornerFrame="); pw.print(mInsetsRoundedCornerFrame);
pw.println();
}
@@ -372,14 +382,12 @@ public class InsetsSource implements Parcelable {
if (mFlags != that.mFlags) return false;
if (excludeInvisibleImeFrames && !mVisible && mType == WindowInsets.Type.ime()) return true;
if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
- if (mInsetsRoundedCornerFrame != that.mInsetsRoundedCornerFrame) return false;
return mFrame.equals(that.mFrame);
}
@Override
public int hashCode() {
- return Objects.hash(mId, mType, mFrame, mVisibleFrame, mVisible, mFlags,
- mInsetsRoundedCornerFrame);
+ return Objects.hash(mId, mType, mFrame, mVisibleFrame, mVisible, mFlags);
}
public InsetsSource(Parcel in) {
@@ -393,7 +401,6 @@ public class InsetsSource implements Parcelable {
}
mVisible = in.readBoolean();
mFlags = in.readInt();
- mInsetsRoundedCornerFrame = in.readBoolean();
}
@Override
@@ -414,7 +421,6 @@ public class InsetsSource implements Parcelable {
}
dest.writeBoolean(mVisible);
dest.writeInt(mFlags);
- dest.writeBoolean(mInsetsRoundedCornerFrame);
}
@Override
@@ -424,7 +430,6 @@ public class InsetsSource implements Parcelable {
+ " mFrame=" + mFrame.toShortString()
+ " mVisible=" + mVisible
+ " mFlags=[" + flagsToString(mFlags) + "]"
- + (mInsetsRoundedCornerFrame ? " insetsRoundedCornerFrame" : "")
+ "}";
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 5b974cdb2bca..61a72772200c 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.InsetsStateProto.DISPLAY_CUTOUT;
import static android.view.InsetsStateProto.DISPLAY_FRAME;
import static android.view.InsetsStateProto.SOURCES;
@@ -219,7 +220,7 @@ public class InsetsState implements Parcelable {
final Rect roundedCornerFrame = new Rect(mRoundedCornerFrame);
for (int i = mSources.size() - 1; i >= 0; i--) {
final InsetsSource source = mSources.valueAt(i);
- if (source.insetsRoundedCornerFrame()) {
+ if (source.hasFlags(FLAG_INSETS_ROUNDED_CORNER)) {
final Insets insets = source.calculateInsets(roundedCornerFrame, false);
roundedCornerFrame.inset(insets);
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 1af8ca2efe11..c703af5af4e6 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1285,6 +1285,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* </ul>
* These values are relative to the state from the last event, not accumulated, so developers
* should make sure to process this axis value for all batched historical events.
+ * <p>
+ * This axis is only set on the first pointer in a motion event.
*/
public static final int AXIS_GESTURE_X_OFFSET = 48;
@@ -1304,6 +1306,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* </ul>
* These values are relative to the state from the last event, not accumulated, so developers
* should make sure to process this axis value for all batched historical events.
+ * <p>
+ * This axis is only set on the first pointer in a motion event.
*/
public static final int AXIS_GESTURE_SCROLL_X_DISTANCE = 50;
@@ -1324,14 +1328,29 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* </ul>
* These values are relative to the state from the last event, not accumulated, so developers
* should make sure to process this axis value for all batched historical events.
+ * <p>
+ * This axis is only set on the first pointer in a motion event.
*/
public static final int AXIS_GESTURE_PINCH_SCALE_FACTOR = 52;
+ /**
+ * Axis constant: the number of fingers being used in a multi-finger swipe gesture.
+ * <p>
+ * <ul>
+ * <li>For a touch pad, reports the number of fingers being used in a multi-finger swipe gesture
+ * (with CLASSIFICATION_MULTI_FINGER_SWIPE).
+ * </ul>
+ * <p>
+ * Since CLASSIFICATION_MULTI_FINGER_SWIPE is a hidden API, so is this axis. It is only set on
+ * the first pointer in a motion event.
+ * @hide
+ */
+ public static final int AXIS_GESTURE_SWIPE_FINGER_COUNT = 53;
+
// NOTE: If you add a new axis here you must also add it to:
// frameworks/native/include/android/input.h
// frameworks/native/libs/input/InputEventLabels.cpp
- // platform/cts/tests/tests/view/src/android/view/cts/MotionEventTest.java
- // (testAxisFromToString)
+ // cts/tests/tests/view/src/android/view/cts/MotionEventTest.java (testAxisFromToString)
// Symbolic names of all axes.
private static final SparseArray<String> AXIS_SYMBOLIC_NAMES = new SparseArray<String>();
@@ -1387,6 +1406,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
names.append(AXIS_GESTURE_SCROLL_X_DISTANCE, "AXIS_GESTURE_SCROLL_X_DISTANCE");
names.append(AXIS_GESTURE_SCROLL_Y_DISTANCE, "AXIS_GESTURE_SCROLL_Y_DISTANCE");
names.append(AXIS_GESTURE_PINCH_SCALE_FACTOR, "AXIS_GESTURE_PINCH_SCALE_FACTOR");
+ names.append(AXIS_GESTURE_SWIPE_FINGER_COUNT, "AXIS_GESTURE_SWIPE_FINGER_COUNT");
}
/**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ddaa71c6b1b5..c11f4975149d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -786,7 +786,11 @@ public final class SurfaceControl implements Parcelable {
mReleaseStack = null;
}
setUnreleasedWarningCallSite(callsite);
- addToRegistry();
+ if (nativeObject != 0) {
+ // Only add valid surface controls to the registry. This is called at the end of this
+ // method since its information is dumped if the process threshold is reached.
+ addToRegistry();
+ }
}
/**
@@ -893,6 +897,10 @@ public final class SurfaceControl implements Parcelable {
"Only buffer layers can set a valid buffer size.");
}
+ if (mName == null) {
+ Log.w(TAG, "Missing name for SurfaceControl", new Throwable());
+ }
+
if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
setBLASTLayer();
}
@@ -1254,6 +1262,9 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Note: Most callers should use {@link SurfaceControl.Builder} or one of the other constructors
+ * to build an instance of a SurfaceControl. This constructor is mainly used for
+ * unparceling and passing into an AIDL call as an out parameter.
* @hide
*/
public SurfaceControl() {
@@ -2495,6 +2506,7 @@ public final class SurfaceControl implements Parcelable {
public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) {
long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject);
SurfaceControl sc = new SurfaceControl();
+ sc.mName = mirrorOf.mName + " (mirror)";
sc.assignNativeObject(nativeObj, "mirrorSurface");
return sc;
}
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index 095189ad03a7..67ac811287cb 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -62,7 +62,6 @@ public class SurfaceControlRegistry {
private static class DefaultReporter implements Reporter {
public void onMaxLayersExceeded(WeakHashMap<SurfaceControl, Long> surfaceControls,
int limit, PrintWriter pw) {
- final int size = Math.min(surfaceControls.size(), limit);
final long now = SystemClock.elapsedRealtime();
final ArrayList<Map.Entry<SurfaceControl, Long>> entries = new ArrayList<>();
for (Map.Entry<SurfaceControl, Long> entry : surfaceControls.entrySet()) {
@@ -71,6 +70,7 @@ public class SurfaceControlRegistry {
// Sort entries by time registered when dumping
// TODO: Or should it sort by name?
entries.sort((o1, o2) -> (int) (o1.getValue() - o2.getValue()));
+ final int size = Math.min(entries.size(), limit);
pw.println("SurfaceControlRegistry");
pw.println("----------------------");
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index d9872174f9be..c8cf7d9a5194 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -171,8 +171,7 @@ public class SurfaceControlViewHost {
public SurfacePackage(@NonNull SurfacePackage other) {
SurfaceControl otherSurfaceControl = other.mSurfaceControl;
if (otherSurfaceControl != null && otherSurfaceControl.isValid()) {
- mSurfaceControl = new SurfaceControl();
- mSurfaceControl.copyFrom(otherSurfaceControl, "SurfacePackage");
+ mSurfaceControl = new SurfaceControl(otherSurfaceControl, "SurfacePackage");
}
mAccessibilityEmbeddedConnection = other.mAccessibilityEmbeddedConnection;
mInputToken = other.mInputToken;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 441636d9a2d6..f1cde3b4bb7e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7734,13 +7734,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
boolean handled = false;
- final ListenerInfo li = mListenerInfo;
+ final OnLongClickListener listener =
+ mListenerInfo == null ? null : mListenerInfo.mOnLongClickListener;
boolean shouldPerformHapticFeedback = true;
- if (li != null && li.mOnLongClickListener != null) {
- handled = li.mOnLongClickListener.onLongClick(View.this);
+ if (listener != null) {
+ handled = listener.onLongClick(View.this);
if (handled) {
- shouldPerformHapticFeedback =
- li.mOnLongClickListener.onLongClickUseDefaultHapticFeedback(View.this);
+ shouldPerformHapticFeedback = listener.onLongClickUseDefaultHapticFeedback(
+ View.this);
}
}
if (!handled) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 7596459b130b..2f04b0c695da 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -658,6 +658,12 @@ public abstract class Window {
void updateStatusBarColor(int color);
/**
+ * Update the status bar appearance.
+ */
+
+ void updateStatusBarAppearance(int appearance);
+
+ /**
* Update the navigation bar color to a forced one.
*/
void updateNavigationBarColor(int color);
@@ -1039,6 +1045,9 @@ public abstract class Window {
if (mDecorCallback != null) {
mDecorCallback.onSystemBarAppearanceChanged(appearance);
}
+ if (mWindowControllerCallback != null) {
+ mWindowControllerCallback.updateStatusBarAppearance(appearance);
+ }
}
/** @hide */
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e95ba797a985..adf772bb896d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -555,6 +555,13 @@ public interface WindowManager extends ViewManager {
int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT = (1 << 9); // 0x200
/**
+ * Transition flag: The transition is prepared when nothing is visible on screen, e.g. screen
+ * is off. The animation handlers can decide whether to skip animations.
+ * @hide
+ */
+ int TRANSIT_FLAG_INVISIBLE = (1 << 10); // 0x400
+
+ /**
* @hide
*/
@IntDef(flag = true, prefix = { "TRANSIT_FLAG_" }, value = {
@@ -567,7 +574,8 @@ public interface WindowManager extends ViewManager {
TRANSIT_FLAG_KEYGUARD_LOCKED,
TRANSIT_FLAG_IS_RECENTS,
TRANSIT_FLAG_KEYGUARD_GOING_AWAY,
- TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT
+ TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT,
+ TRANSIT_FLAG_INVISIBLE,
})
@Retention(RetentionPolicy.SOURCE)
@interface TransitionFlags {}
@@ -3755,6 +3763,7 @@ public interface WindowManager extends ViewManager {
* This value is ignored if {@link #preferredDisplayModeId} is set.
* @hide
*/
+ @TestApi
public float preferredMinDisplayRefreshRate;
/**
@@ -3763,6 +3772,7 @@ public interface WindowManager extends ViewManager {
* This value is ignored if {@link #preferredDisplayModeId} is set.
* @hide
*/
+ @TestApi
public float preferredMaxDisplayRefreshRate;
/** Indicates whether this window wants the HDR conversion is disabled. */
@@ -4244,17 +4254,6 @@ public interface WindowManager extends ViewManager {
public InsetsFrameProvider[] providedInsets;
/**
- * If specified, the frame that used to calculate relative {@link RoundedCorner} will be
- * the window frame of this window minus the insets that this window provides.
- *
- * Task bar will draw fake rounded corners above itself, so we need this insets to calculate
- * correct rounded corners for this window.
- *
- * @hide
- */
- public boolean insetsRoundedCornerFrame = false;
-
- /**
* {@link LayoutParams} to be applied to the window when layout with a assigned rotation.
* This will make layout during rotation change smoothly.
*
@@ -4710,7 +4709,6 @@ public interface WindowManager extends ViewManager {
out.writeBoolean(mFitInsetsIgnoringVisibility);
out.writeBoolean(preferMinimalPostProcessing);
out.writeInt(mBlurBehindRadius);
- out.writeBoolean(insetsRoundedCornerFrame);
out.writeBoolean(mWallpaperTouchEventsEnabled);
out.writeTypedArray(providedInsets, 0 /* parcelableFlags */);
checkNonRecursiveParams();
@@ -4782,7 +4780,6 @@ public interface WindowManager extends ViewManager {
mFitInsetsIgnoringVisibility = in.readBoolean();
preferMinimalPostProcessing = in.readBoolean();
mBlurBehindRadius = in.readInt();
- insetsRoundedCornerFrame = in.readBoolean();
mWallpaperTouchEventsEnabled = in.readBoolean();
providedInsets = in.createTypedArray(InsetsFrameProvider.CREATOR);
paramsForRotation = in.createTypedArray(LayoutParams.CREATOR);
@@ -5090,11 +5087,6 @@ public interface WindowManager extends ViewManager {
changes |= LAYOUT_CHANGED;
}
- if (insetsRoundedCornerFrame != o.insetsRoundedCornerFrame) {
- insetsRoundedCornerFrame = o.insetsRoundedCornerFrame;
- changes |= LAYOUT_CHANGED;
- }
-
if (paramsForRotation != o.paramsForRotation) {
if ((changes & LAYOUT_CHANGED) == 0) {
if (paramsForRotation != null && o.paramsForRotation != null
@@ -5332,10 +5324,6 @@ public interface WindowManager extends ViewManager {
sb.append(prefix).append(" ").append(providedInsets[i]);
}
}
- if (insetsRoundedCornerFrame) {
- sb.append(" insetsRoundedCornerFrame=");
- sb.append(insetsRoundedCornerFrame);
- }
if (paramsForRotation != null && paramsForRotation.length != 0) {
sb.append(System.lineSeparator());
sb.append(prefix).append(" paramsForRotation:");
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 668351b949c1..c37e311209df 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -352,6 +352,30 @@ public final class ContentCaptureManager {
public static final String DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING =
"disable_flush_for_view_tree_appearing";
+ /**
+ * Enables the content protection receiver.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER =
+ "enable_content_protection_receiver";
+
+ /**
+ * Sets the size of the app blocklist for the content protection flow.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE =
+ "content_protection_apps_blocklist_size";
+
+ /**
+ * Sets the size of the in-memory ring buffer for the content protection flow.
+ *
+ * @hide
+ */
+ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE =
+ "content_protection_buffer_size";
+
/** @hide */
@TestApi
public static final int LOGGING_LEVEL_OFF = 0;
@@ -384,6 +408,14 @@ public final class ContentCaptureManager {
public static final int DEFAULT_LOG_HISTORY_SIZE = 10;
/** @hide */
public static final boolean DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING = false;
+ /** @hide */
+ public static final boolean DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER = true;
+ /** @hide */
+ public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false;
+ /** @hide */
+ public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 1000;
+ /** @hide */
+ public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150;
private final Object mLock = new Object();
@@ -425,11 +457,11 @@ public final class ContentCaptureManager {
/** @hide */
static class StrippedContext {
- final String mPackageName;
- final String mContext;
+ @NonNull final String mPackageName;
+ @NonNull final String mContext;
final @UserIdInt int mUserId;
- private StrippedContext(Context context) {
+ private StrippedContext(@NonNull Context context) {
mPackageName = context.getPackageName();
mContext = context.toString();
mUserId = context.getUserId();
@@ -440,6 +472,7 @@ public final class ContentCaptureManager {
return mContext;
}
+ @NonNull
public String getPackageName() {
return mPackageName;
}
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
index d1eda9648520..a958bbec8f90 100644
--- a/core/java/android/view/contentcapture/OWNERS
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -6,4 +6,5 @@ markpun@google.com
lpeter@google.com
tymtsai@google.com
hackz@google.com
-volnov@google.com \ No newline at end of file
+shivanker@google.com
+volnov@google.com
diff --git a/core/java/android/view/contentprotection/ContentProtectionUtils.java b/core/java/android/view/contentprotection/ContentProtectionUtils.java
new file mode 100644
index 000000000000..9abf6f10d05d
--- /dev/null
+++ b/core/java/android/view/contentprotection/ContentProtectionUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.contentprotection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ViewNode;
+
+/**
+ * Utilities for reading data from {@link ContentCaptureEvent} and {@link ViewNode}.
+ *
+ * @hide
+ */
+public final class ContentProtectionUtils {
+
+ /** Returns the text extracted directly from the {@link ContentCaptureEvent}, if set. */
+ @Nullable
+ public static String getEventText(@NonNull ContentCaptureEvent event) {
+ CharSequence text = event.getText();
+ if (text == null) {
+ return null;
+ }
+ return text.toString();
+ }
+
+ /** Returns the text extracted from the event's {@link ViewNode}, if set. */
+ @Nullable
+ public static String getViewNodeText(@NonNull ContentCaptureEvent event) {
+ ViewNode viewNode = event.getViewNode();
+ if (viewNode == null) {
+ return null;
+ }
+ return getViewNodeText(viewNode);
+ }
+
+ /** Returns the text extracted directly from the {@link ViewNode}, if set. */
+ @Nullable
+ public static String getViewNodeText(@NonNull ViewNode viewNode) {
+ CharSequence text = viewNode.getText();
+ if (text == null) {
+ return null;
+ }
+ return text.toString();
+ }
+}
diff --git a/core/java/android/view/contentprotection/OWNERS b/core/java/android/view/contentprotection/OWNERS
new file mode 100644
index 000000000000..b3583a7f6ab1
--- /dev/null
+++ b/core/java/android/view/contentprotection/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 544200
+
+include /core/java/android/view/contentcapture/OWNERS
+
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 41ef44e1ac1f..40b060ad0bbf 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -4361,15 +4361,14 @@ public final class InputMethodManager {
* @param icProto {@link InputConnection} call data in proto format.
* @hide
*/
- @GuardedBy("mH")
public void dumpDebug(ProtoOutputStream proto, @Nullable byte[] icProto) {
- if (!isImeSessionAvailableLocked()) {
- return;
- }
-
- proto.write(DISPLAY_ID, mDisplayId);
- final long token = proto.start(INPUT_METHOD_MANAGER);
synchronized (mH) {
+ if (!isImeSessionAvailableLocked()) {
+ return;
+ }
+
+ proto.write(DISPLAY_ID, mDisplayId);
+ final long token = proto.start(INPUT_METHOD_MANAGER);
proto.write(CUR_ID, mCurBindState.mImeId);
proto.write(FULLSCREEN_MODE, mFullscreenMode);
proto.write(ACTIVE, mActive);
diff --git a/core/java/android/view/inputmethod/TextAppearanceInfo.java b/core/java/android/view/inputmethod/TextAppearanceInfo.java
index 05717dd5d930..7eee33f7f617 100644
--- a/core/java/android/view/inputmethod/TextAppearanceInfo.java
+++ b/core/java/android/view/inputmethod/TextAppearanceInfo.java
@@ -238,7 +238,10 @@ public final class TextAppearanceInfo implements Parcelable {
.setFontFeatureSettings(textPaint.getFontFeatureSettings())
.setFontVariationSettings(textPaint.getFontVariationSettings())
.setTextScaleX(textPaint.getTextScaleX())
- .setTextColor(textPaint.getColor())
+ // When there is a hint text (text length is 0), the text color should be the normal
+ // text color rather than hint text color.
+ .setTextColor(text.length() == 0
+ ? textView.getCurrentTextColor() : textPaint.getColor())
.setLinkTextColor(textPaint.linkColor)
.setAllCaps(textView.isAllCaps())
.setFallbackLineSpacing(textView.isFallbackLineSpacing())
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 34e6e49d390f..3be8c3d6b502 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -232,6 +232,7 @@ public class RemoteViews implements Parcelable, Filter {
private static final int NIGHT_MODE_REFLECTION_ACTION_TAG = 30;
private static final int SET_REMOTE_COLLECTION_ITEMS_ADAPTER_TAG = 31;
private static final int ATTRIBUTE_REFLECTION_ACTION_TAG = 32;
+ private static final int SET_REMOTE_ADAPTER_TAG = 33;
/** @hide **/
@IntDef(prefix = "MARGIN_", value = {
@@ -726,6 +727,11 @@ public class RemoteViews implements Parcelable, Filter {
mActions.get(i).visitUris(visitor);
}
}
+ if (mSizedRemoteViews != null) {
+ for (int i = 0; i < mSizedRemoteViews.size(); i++) {
+ mSizedRemoteViews.get(i).visitUris(visitor);
+ }
+ }
if (mLandscape != null) {
mLandscape.visitUris(visitor);
}
@@ -955,6 +961,11 @@ public class RemoteViews implements Parcelable, Filter {
return SET_REMOTE_VIEW_ADAPTER_LIST_TAG;
}
+ @Override
+ public String getUniqueKey() {
+ return (SET_REMOTE_ADAPTER_TAG + "_" + viewId);
+ }
+
int viewTypeCount;
ArrayList<RemoteViews> list;
}
@@ -1077,6 +1088,11 @@ public class RemoteViews implements Parcelable, Filter {
public int getActionTag() {
return SET_REMOTE_COLLECTION_ITEMS_ADAPTER_TAG;
}
+
+ @Override
+ public String getUniqueKey() {
+ return (SET_REMOTE_ADAPTER_TAG + "_" + viewId);
+ }
}
private class SetRemoteViewsAdapterIntent extends Action {
@@ -1845,7 +1861,7 @@ public class RemoteViews implements Parcelable, Filter {
}
@Override
- public final void visitUris(@NonNull Consumer<Uri> visitor) {
+ public void visitUris(@NonNull Consumer<Uri> visitor) {
switch (this.type) {
case URI:
final Uri uri = (Uri) getParameterValue(null);
@@ -2308,6 +2324,14 @@ public class RemoteViews implements Parcelable, Filter {
public int getActionTag() {
return NIGHT_MODE_REFLECTION_ACTION_TAG;
}
+
+ @Override
+ public void visitUris(@NonNull Consumer<Uri> visitor) {
+ if (this.type == ICON) {
+ visitIconUri((Icon) mDarkValue, visitor);
+ visitIconUri((Icon) mLightValue, visitor);
+ }
+ }
}
/**
@@ -2598,6 +2622,11 @@ public class RemoteViews implements Parcelable, Filter {
public int getActionTag() {
return VIEW_GROUP_ACTION_ADD_TAG;
}
+
+ @Override
+ public final void visitUris(@NonNull Consumer<Uri> visitor) {
+ mNestedViews.visitUris(visitor);
+ }
}
/**
diff --git a/core/java/android/window/SnapshotDrawerUtils.java b/core/java/android/window/SnapshotDrawerUtils.java
index 52e17ca4ab0d..f40874b77536 100644
--- a/core/java/android/window/SnapshotDrawerUtils.java
+++ b/core/java/android/window/SnapshotDrawerUtils.java
@@ -43,6 +43,7 @@ import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_AT
import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityThread;
@@ -183,7 +184,7 @@ public class SnapshotDrawerUtils {
// We consider nearly matched dimensions as there can be rounding errors and the user
// won't notice very minute differences from scaling one dimension more than the other
- final boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot);
+ boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot);
// Keep a reference to it such that it doesn't get destroyed when finalized.
SurfaceControl childSurfaceControl = new SurfaceControl.Builder(session)
@@ -199,8 +200,20 @@ public class SnapshotDrawerUtils {
// still hidden.
mTransaction.show(childSurfaceControl);
if (aspectRatioMismatch) {
- // Clip off ugly navigation bar.
- final Rect crop = calculateSnapshotCrop();
+ Rect crop = null;
+ final Rect letterboxInsets = mSnapshot.getLetterboxInsets();
+ if (letterboxInsets.left != 0 || letterboxInsets.top != 0
+ || letterboxInsets.right != 0 || letterboxInsets.bottom != 0) {
+ // Clip off letterbox.
+ crop = calculateSnapshotCrop(letterboxInsets);
+ // If the snapshot can cover the frame, then no need to draw background.
+ aspectRatioMismatch = !isAspectRatioMatch(mFrame, crop);
+ }
+ // if letterbox doesn't match window frame, try crop by content insets
+ if (aspectRatioMismatch) {
+ // Clip off ugly navigation bar.
+ crop = calculateSnapshotCrop(mSnapshot.getContentInsets());
+ }
frame = calculateSnapshotFrame(crop);
mTransaction.setWindowCrop(childSurfaceControl, crop);
mTransaction.setPosition(childSurfaceControl, frame.left, frame.top);
@@ -242,14 +255,13 @@ public class SnapshotDrawerUtils {
/**
* Calculates the snapshot crop in snapshot coordinate space.
- *
+ * @param insets Content insets or Letterbox insets
* @return crop rect in snapshot coordinate space.
*/
- Rect calculateSnapshotCrop() {
+ Rect calculateSnapshotCrop(@NonNull Rect insets) {
final Rect rect = new Rect();
final HardwareBuffer snapshot = mSnapshot.getHardwareBuffer();
rect.set(0, 0, snapshot.getWidth(), snapshot.getHeight());
- final Rect insets = mSnapshot.getContentInsets();
final float scaleX = (float) snapshot.getWidth() / mSnapshot.getTaskSize().x;
final float scaleY = (float) snapshot.getHeight() / mSnapshot.getTaskSize().y;
@@ -334,6 +346,15 @@ public class SnapshotDrawerUtils {
- ((float) frame.width() / frame.height())) <= 0.01f;
}
+ private static boolean isAspectRatioMatch(Rect frame1, Rect frame2) {
+ if (frame1.isEmpty() || frame2.isEmpty()) {
+ return false;
+ }
+ return Math.abs(
+ ((float) frame2.width() / frame2.height())
+ - ((float) frame1.width() / frame1.height())) <= 0.01f;
+ }
+
/**
* Get or create a TaskDescription from a RunningTaskInfo.
*/
diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java
index dfdff9ef97ce..5d14698c82b3 100644
--- a/core/java/android/window/SurfaceSyncGroup.java
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -26,6 +26,7 @@ import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.Trace;
import android.util.ArraySet;
@@ -800,22 +801,25 @@ public final class SurfaceSyncGroup {
}
private void addTimeout() {
+ Looper looper = null;
synchronized (sHandlerThreadLock) {
if (sHandlerThread == null) {
sHandlerThread = new HandlerThread("SurfaceSyncGroupTimer");
sHandlerThread.start();
}
+
+ looper = sHandlerThread.getLooper();
}
synchronized (mLock) {
- if (mTimeoutAdded || mTimeoutDisabled) {
+ if (mTimeoutAdded || mTimeoutDisabled || looper == null) {
// We only need one timeout for the entire SurfaceSyncGroup since we just want to
// ensure it doesn't stay stuck forever.
return;
}
if (mHandler == null) {
- mHandler = new Handler(sHandlerThread.getLooper());
+ mHandler = new Handler(looper);
}
mTimeoutAdded = true;
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java
index b7bb6082296e..41b6d31661ce 100644
--- a/core/java/android/window/TaskSnapshot.java
+++ b/core/java/android/window/TaskSnapshot.java
@@ -28,6 +28,7 @@ import android.hardware.HardwareBuffer;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.view.Surface;
import android.view.WindowInsetsController;
@@ -38,6 +39,9 @@ import android.view.WindowInsetsController;
public class TaskSnapshot implements Parcelable {
// Identifier of this snapshot
private final long mId;
+ // The elapsed real time (in nanoseconds) when this snapshot was captured, not intended for use outside the
+ // process in which the snapshot was taken (ie. this is not parceled)
+ private final long mCaptureTime;
// Top activity in task when snapshot was taken
private final ComponentName mTopActivityComponent;
private final HardwareBuffer mSnapshot;
@@ -65,7 +69,7 @@ public class TaskSnapshot implements Parcelable {
// Must be one of the named color spaces, otherwise, always use SRGB color space.
private final ColorSpace mColorSpace;
- public TaskSnapshot(long id,
+ public TaskSnapshot(long id, long captureTime,
@NonNull ComponentName topActivityComponent, HardwareBuffer snapshot,
@NonNull ColorSpace colorSpace, int orientation, int rotation, Point taskSize,
Rect contentInsets, Rect letterboxInsets, boolean isLowResolution,
@@ -73,6 +77,7 @@ public class TaskSnapshot implements Parcelable {
@WindowInsetsController.Appearance int appearance, boolean isTranslucent,
boolean hasImeSurface) {
mId = id;
+ mCaptureTime = captureTime;
mTopActivityComponent = topActivityComponent;
mSnapshot = snapshot;
mColorSpace = colorSpace.getId() < 0
@@ -92,6 +97,7 @@ public class TaskSnapshot implements Parcelable {
private TaskSnapshot(Parcel source) {
mId = source.readLong();
+ mCaptureTime = SystemClock.elapsedRealtimeNanos();
mTopActivityComponent = ComponentName.readFromParcel(source);
mSnapshot = source.readTypedObject(HardwareBuffer.CREATOR);
int colorSpaceId = source.readInt();
@@ -119,6 +125,14 @@ public class TaskSnapshot implements Parcelable {
}
/**
+ * @return The elapsed real time (in nanoseconds) when this snapshot was captured. This time is
+ * only valid in the process where this snapshot was taken.
+ */
+ public long getCaptureTime() {
+ return mCaptureTime;
+ }
+
+ /**
* @return The top activity component for the task at the point this snapshot was taken.
*/
public ComponentName getTopActivityComponent() {
@@ -268,6 +282,7 @@ public class TaskSnapshot implements Parcelable {
final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
return "TaskSnapshot{"
+ " mId=" + mId
+ + " mCaptureTime=" + mCaptureTime
+ " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
+ " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+ " mColorSpace=" + mColorSpace.toString()
@@ -296,6 +311,7 @@ public class TaskSnapshot implements Parcelable {
/** Builder for a {@link TaskSnapshot} object */
public static final class Builder {
private long mId;
+ private long mCaptureTime;
private ComponentName mTopActivity;
private HardwareBuffer mSnapshot;
private ColorSpace mColorSpace;
@@ -317,6 +333,11 @@ public class TaskSnapshot implements Parcelable {
return this;
}
+ public Builder setCaptureTime(long captureTime) {
+ mCaptureTime = captureTime;
+ return this;
+ }
+
public Builder setTopActivityComponent(ComponentName name) {
mTopActivity = name;
return this;
@@ -400,6 +421,7 @@ public class TaskSnapshot implements Parcelable {
public TaskSnapshot build() {
return new TaskSnapshot(
mId,
+ mCaptureTime,
mTopActivity,
mSnapshot,
mColorSpace,
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 8c05130bf5fe..a92ca8a4d3f2 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -424,8 +424,8 @@ public final class TransitionInfo implements Parcelable {
case TRANSIT_NONE: return "NONE";
case TRANSIT_OPEN: return "OPEN";
case TRANSIT_CLOSE: return "CLOSE";
- case TRANSIT_TO_FRONT: return "SHOW";
- case TRANSIT_TO_BACK: return "HIDE";
+ case TRANSIT_TO_FRONT: return "TO_FRONT";
+ case TRANSIT_TO_BACK: return "TO_BACK";
case TRANSIT_CHANGE: return "CHANGE";
default: return "<unknown:" + mode + ">";
}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 22b2ec09c034..421d9983d6b7 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -31,6 +31,8 @@ import android.util.Log;
import android.view.IWindow;
import android.view.IWindowSession;
+import androidx.annotation.VisibleForTesting;
+
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -66,7 +68,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
/** Convenience hashmap to quickly decide if a callback has been added. */
private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
/** Holds all callbacks by priorities. */
- private final TreeMap<Integer, ArrayList<OnBackInvokedCallback>>
+
+ @VisibleForTesting
+ public final TreeMap<Integer, ArrayList<OnBackInvokedCallback>>
mOnBackInvokedCallbacks = new TreeMap<>();
private Checker mChecker;
diff --git a/core/java/com/android/internal/accessibility/common/MagnificationConstants.java b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java
index 94c230bc94fb..95c3419180a9 100644
--- a/core/java/com/android/internal/accessibility/common/MagnificationConstants.java
+++ b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java
@@ -27,4 +27,10 @@ public final class MagnificationConstants {
* the min value, there will be no obvious magnification effect.
*/
public static final float PERSISTED_SCALE_MIN_VALUE = 1.3f;
+
+ /** Minimum supported value for magnification scale. */
+ public static final float SCALE_MIN_VALUE = 1.0f;
+
+ /** Maximum supported value for magnification scale. */
+ public static final float SCALE_MAX_VALUE = 8.0f;
}
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 1f7640d97b4d..7c4252e7aa5d 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -258,6 +258,10 @@ public final class AccessibilityStatsLogUtils {
}
private static int convertToLoggingMagnificationScale(float scale) {
- return (int) (scale * 100);
+ // per b/269366674, we make every 10% a bucket for both privacy and readability concern.
+ // For example
+ // 1. both 2.30f(230%) and 2.36f(236%) would return 230 as bucket id.
+ // 2. bucket id 370 means scale range in [370%, 379%]
+ return ((int) (scale * 10)) * 10;
}
}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 8135f9cd2f46..4cb592eedfdc 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -571,6 +571,11 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String COMBINED_BROADCAST_ENABLED = "combined_broadcast_enabled";
+ /**
+ * (boolean) Whether to allow cursor hover states for certain elements.
+ */
+ public static final String CURSOR_HOVER_STATES_ENABLED = "cursor_hover_states_enabled";
+
private SystemUiDeviceConfigFlags() {
}
}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 86c2893c9fab..3d95dd341cc0 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -80,7 +80,7 @@ public class SystemUiSystemPropertiesFlags {
/** Gating the logging of DND state change events. */
public static final Flag LOG_DND_STATE_EVENTS =
- devFlag("persist.sysui.notification.log_dnd_state_events");
+ releasedFlag("persist.sysui.notification.log_dnd_state_events");
}
//// == End of flags. Everything below this line is the implementation. == ////
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index e530aec2119a..869b69611eba 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -28,6 +28,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_ICON;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS;
@@ -258,8 +259,16 @@ public class InteractionJankMonitor {
public static final int CUJ_IME_INSETS_ANIMATION = 69;
public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = 70;
public static final int CUJ_LAUNCHER_OPEN_SEARCH_RESULT = 71;
+ // 72 - 77 are reserved for b/281564325.
- private static final int LAST_CUJ = CUJ_LAUNCHER_OPEN_SEARCH_RESULT;
+ /**
+ * In some cases when we do not have any end-target, we play a simple slide-down animation.
+ * eg: Open an app from Overview/Task switcher such that there is no home-screen icon.
+ * eg: Exit the app using back gesture.
+ */
+ public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK = 78;
+
+ private static final int LAST_CUJ = CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
private static final int NO_STATSD_LOGGING = -1;
// Used to convert CujType to InteractionType enum value for statsd logging.
@@ -340,6 +349,14 @@ public class InteractionJankMonitor {
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_SEARCH_RESULT] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT;
+ // 72 - 77 are reserved for b/281564325.
+ CUJ_TO_STATSD_INTERACTION_TYPE[72] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[73] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[74] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[75] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[76] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[77] = NO_STATSD_LOGGING;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
}
private static class InstanceHolder {
@@ -439,6 +456,7 @@ public class InteractionJankMonitor {
CUJ_IME_INSETS_ANIMATION,
CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION,
CUJ_LAUNCHER_OPEN_SEARCH_RESULT,
+ CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -1050,6 +1068,8 @@ public class InteractionJankMonitor {
return "LOCKSCREEN_CLOCK_MOVE_ANIMATION";
case CUJ_LAUNCHER_OPEN_SEARCH_RESULT:
return "LAUNCHER_OPEN_SEARCH_RESULT";
+ case CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK:
+ return "LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
index 3ba4ea55b5d3..80d753c7ed09 100644
--- a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
+++ b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
@@ -120,6 +120,10 @@ public class AnrLatencyTracker implements AutoCloseable {
private long mPreDumpIfLockTooSlowStartUptime;
private long mPreDumpIfLockTooSlowDuration = 0;
+ private long mNotifyAppUnresponsiveStartUptime;
+ private long mNotifyAppUnresponsiveDuration = 0;
+ private long mNotifyWindowUnresponsiveStartUptime;
+ private long mNotifyWindowUnresponsiveDuration = 0;
private final int mAnrRecordPlacedOnQueueCookie =
sNextAnrRecordPlacedOnQueueCookieGenerator.incrementAndGet();
@@ -425,11 +429,36 @@ public class AnrLatencyTracker implements AutoCloseable {
anrSkipped("dumpStackTraces");
}
+ /** Records the start of AnrController#notifyAppUnresponsive. */
+ public void notifyAppUnresponsiveStarted() {
+ mNotifyAppUnresponsiveStartUptime = getUptimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
+ }
+
+ /** Records the end of AnrController#notifyAppUnresponsive. */
+ public void notifyAppUnresponsiveEnded() {
+ mNotifyAppUnresponsiveDuration = getUptimeMillis() - mNotifyAppUnresponsiveStartUptime;
+ Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
+ /** Records the start of AnrController#notifyWindowUnresponsive. */
+ public void notifyWindowUnresponsiveStarted() {
+ mNotifyWindowUnresponsiveStartUptime = getUptimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyWindowUnresponsive()");
+ }
+
+ /** Records the end of AnrController#notifyWindowUnresponsive. */
+ public void notifyWindowUnresponsiveEnded() {
+ mNotifyWindowUnresponsiveDuration = getUptimeMillis()
+ - mNotifyWindowUnresponsiveStartUptime;
+ Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
/**
* Returns latency data as a comma separated value string for inclusion in ANR report.
*/
public String dumpAsCommaSeparatedArrayWithHeader() {
- return "DurationsV4: " + mAnrTriggerUptime
+ return "DurationsV5: " + mAnrTriggerUptime
/* triggering_to_app_not_responding_duration = */
+ "," + (mAppNotRespondingStartUptime - mAnrTriggerUptime)
/* app_not_responding_duration = */
@@ -480,6 +509,10 @@ public class AnrLatencyTracker implements AutoCloseable {
+ "," + (mCopyingFirstPidSucceeded ? 1 : 0)
/* preDumpIfLockTooSlow_duration = */
+ "," + mPreDumpIfLockTooSlowDuration
+ /* notifyAppUnresponsive_duration = */
+ + "," + mNotifyAppUnresponsiveDuration
+ /* notifyWindowUnresponsive_duration = */
+ + "," + mNotifyWindowUnresponsiveDuration
+ "\n\n";
}
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java
index 93765cdf0890..8870096f3db7 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLog.java
@@ -16,6 +16,8 @@
package com.android.internal.protolog.common;
+import android.util.Log;
+
/**
* ProtoLog API - exposes static logging methods. Usage of this API is similar
* to {@code android.utils.Log} class. Instead of plain text log messages each call consists of
@@ -53,6 +55,9 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.d(group.getTag(), String.format(messageString, args));
+ }
}
/**
@@ -68,6 +73,9 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.v(group.getTag(), String.format(messageString, args));
+ }
}
/**
@@ -83,6 +91,9 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.i(group.getTag(), String.format(messageString, args));
+ }
}
/**
@@ -98,6 +109,9 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.w(group.getTag(), String.format(messageString, args));
+ }
}
/**
@@ -113,6 +127,9 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.e(group.getTag(), String.format(messageString, args));
+ }
}
/**
@@ -128,5 +145,8 @@ public class ProtoLog {
throw new UnsupportedOperationException(
"ProtoLog calls MUST be processed with ProtoLogTool");
}
+ if (group.isLogToLogcat()) {
+ Log.wtf(group.getTag(), String.format(messageString, args));
+ }
}
}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index f2776353fd1b..116c301c28f0 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -367,28 +367,42 @@ public class LatencyTracker {
* using a single static object.
*/
@VisibleForTesting
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
public void startListeningForLatencyTrackerConfigChanges() {
final Context context = ActivityThread.currentApplication();
- if (context != null
- && context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
- // Post initialization to the background in case we're running on the main thread.
- BackgroundThread.getHandler().post(() -> this.updateProperties(
- DeviceConfig.getProperties(NAMESPACE_LATENCY_TRACKER)));
- DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_LATENCY_TRACKER,
- BackgroundThread.getExecutor(), mOnPropertiesChangedListener);
- } else {
+ if (context == null) {
if (DEBUG) {
- if (context == null) {
- Log.d(TAG, "No application for " + ActivityThread.currentActivityThread());
- } else {
- synchronized (mLock) {
- Log.d(TAG, "Initialized the LatencyTracker."
- + " (No READ_DEVICE_CONFIG permission to change configs)"
- + " enabled=" + mEnabled + ", package=" + context.getPackageName());
- }
- }
+ Log.d(TAG, "No application for package: " + ActivityThread.currentPackageName());
}
+ return;
}
+ if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
+ if (DEBUG) {
+ synchronized (mLock) {
+ Log.d(TAG, "Initialized the LatencyTracker."
+ + " (No READ_DEVICE_CONFIG permission to change configs)"
+ + " enabled=" + mEnabled + ", package=" + context.getPackageName());
+ }
+ }
+ return;
+ }
+
+ // Post initialization to the background in case we're running on the main thread.
+ BackgroundThread.getHandler().post(() -> {
+ try {
+ this.updateProperties(
+ DeviceConfig.getProperties(NAMESPACE_LATENCY_TRACKER));
+ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_LATENCY_TRACKER,
+ BackgroundThread.getExecutor(), mOnPropertiesChangedListener);
+ } catch (SecurityException ex) {
+ // In case of running tests that the main thread passes the check,
+ // but the background thread doesn't have necessary permissions.
+ // Swallow it since it's ok to ignore device config changes in the tests.
+ Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
+ + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
+ + ", package=" + context.getPackageName());
+ }
+ });
}
/**
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 2695b9c7651f..1ac5e1f12bfa 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -82,7 +82,7 @@ public class ImageFloatingTextView extends TextView {
.setIncludePad(getIncludeFontPadding())
.setUseLineSpacingFromFallbacks(true)
.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
- .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL_FAST);
int maxLines;
if (mMaxLinesForHeight > 0) {
maxLines = mMaxLinesForHeight;
diff --git a/core/proto/android/companion/telecom.proto b/core/proto/android/companion/telecom.proto
index 700baa1f4ee5..7fe2467032cb 100644
--- a/core/proto/android/companion/telecom.proto
+++ b/core/proto/android/companion/telecom.proto
@@ -45,10 +45,18 @@ message Telecom {
AUDIO_PROCESSING = 5;
RINGING_SIMULATED = 6;
DISCONNECTED = 7;
+ DIALING = 8;
}
Status status = 3;
repeated Control controls = 4;
+
+ enum Direction {
+ UNKNOWN_DIRECTION = 0;
+ INCOMING = 1;
+ OUTGOING = 2;
+ }
+ Direction direction = 5;
}
message Request {
diff --git a/core/proto/android/input/keyboard_configured.proto b/core/proto/android/input/keyboard_configured.proto
new file mode 100644
index 000000000000..16990087b319
--- /dev/null
+++ b/core/proto/android/input/keyboard_configured.proto
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package com.android.internal.os;
+
+option java_outer_classname = "KeyboardConfiguredProto";
+
+/**
+ * RepeatedKeyboardLayout proto from input_extension_atoms.proto,
+ * duplicated here so that it's accessible in the build.
+ * Must be kept in sync with the version in input_extension_atoms.proto.
+ */
+
+// Message containing the repeated field for KeyboardLayoutConfig
+message RepeatedKeyboardLayoutConfig {
+ repeated KeyboardLayoutConfig keyboard_layout_config = 1;
+}
+
+// Keyboard layout configured when the device is connected
+// used in KeyboardConfigured atom
+message KeyboardLayoutConfig {
+ // Keyboard configuration details
+ // Layout type mappings found at:
+ // frameworks/base/core/res/res/values/attrs.xml
+ optional int32 keyboard_layout_type = 1;
+ // PK language language tag (e.g. en-US, ru-Cyrl, etc). This will follow
+ // BCP-47 language tag standards.
+ optional string keyboard_language_tag = 2;
+ // Selected keyboard layout name (e.g. English(US), English(Dvorak), etc.)
+ optional string keyboard_layout_name = 3;
+ // Criteria for layout selection (such as user, device, virtual keyboard based)
+ // IntDef annotation at:
+ // services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+ optional int32 layout_selection_criteria = 4;
+}
diff --git a/core/res/res/layout/language_picker_section_header.xml b/core/res/res/layout/language_picker_section_header.xml
index 58042f9a42f8..54ac6776dd04 100644
--- a/core/res/res/layout/language_picker_section_header.xml
+++ b/core/res/res/layout/language_picker_section_header.xml
@@ -25,4 +25,5 @@
android:textColor="?android:attr/colorAccent"
android:textStyle="bold"
android:id="@+id/language_picker_header"
- tools:text="@string/language_picker_section_all"/>
+ tools:text="@string/language_picker_section_all"
+ android:scrollbars="none"/>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 33e7ec97d079..a6b1fdbc588d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou foon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Hierdie program is vir ’n ouer weergawe van Android gebou. Dit sal dalk nie behoorlik werk nie en dit sluit nie die jongste sekuriteit en privaatheidbeskermings in nie. Kyk of daar ’n opdatering is of kontak die program se ontwikkelaar."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kyk vir opdatering"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Hierdie app is nie met die jongste weergawe van Android versoenbaar nie. Kyk of daar ’n opdatering is, of kontak die app se ontwikkelaar."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jy het nuwe boodskappe"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Maak SMS-program oop om te bekyk"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sommige funksies kan beperk wees"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 90137083e95f..5a4f3c1ce8e1 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ይህ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ይህ መተግበሪያ የተገነባው ለቆየ የAndroid ስሪት ነበር። በትክክል ላይሰራ ይችላል እና የቅርብ ጊዜዎቹን የደህንነት እና የግላዊነት ጥበቃዎች አያካትትም። ዝማኔ ካለ ይፈትሹ ወይም የመተግበሪያውን ገንቢ ያነጋግሩ።"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ዝማኔ ካለ አረጋግጥ"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"አዲስ መልዕክቶች አለዎት"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ለመመልከት የኤስኤምኤስ መተግበሪያ ይክፈቱ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"አንዳንድ ተግባሮች የተገደቡ ሊሆኑ ይችላሉ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bcfdef20ffca..26610733276c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1979,6 +1979,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"لا يمكن الوصول إلى هذه الإعدادات على <xliff:g id="DEVICE">%1$s</xliff:g>. بدلاً من ذلك، جرِّب استخدام هاتفك."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏تم إنشاء هذا التطبيق لإصدار قديم من Android. قد لا يعمل بشكل صحيح كما أنه لا يشتمِل على أحدث الإجراءات لحماية الأمان والخصوصية. ابحث عن تحديث أو تواصَل مع مطوّر التطبيق."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن تحديث"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"لديك رسائل جديدة"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏فتح تطبيق الرسائل القصيرة SMS للعرض"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"قد تكون بعض الوظائف مُقيّدة."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 875f60459d41..11694a20a2d5 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"এইটো আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"এই এপ্‌টো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে বনোৱা হৈছিল। এইটোৱে সঠিকভাৱে কাম নকৰিব পাৰে আৰু ইয়াত শেহতীয়া সুৰক্ষা আৰু গোপনীয়তা সম্পৰ্কীয় সুৰক্ষাসমূহ নাথাকে। কোনো আপডে’ট আছে নেকি চাওক অথবা এপৰ বিকাশকৰ্তাগৰাকীৰ সৈতে যোগাযোগ কৰক।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডে’ট আছে নেকি চাওক"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপুনি নতুন বার্তা লাভ কৰিছে"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"চাবলৈ এছএমএছ এপ্ খোলক"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"কিছুমান কাৰ্যকাৰিতা সীমিত হ’ব পাৰে"</string>
@@ -2165,20 +2167,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"কৰ্মস্থানৰ <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"কৰ্মস্থানৰ <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"কাম সম্পৰ্কীয় এপৰ পৰা কল কৰিবনে?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ইয়াৰ সলনি কাম সম্পৰ্কীয় এপ্ ব্যৱহাৰ কৰিবনে?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা কল কৰিবলৈ অনুমতি দিয়ে"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা বাৰ্তা পঠিওৱাৰ অনুমতি দিয়ে"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"কৰ্মস্থানৰ ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"কল কৰক"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"সলনি কৰক"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ছিম কৰ্পৰে\'ট আনলক কৰা পিন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 6e3a1cc992de..45b67ebabb2a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızda buna giriş mümkün deyil. Telefonunuzda sınayın."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu tətbiq köhnə Android versiyası üçün nəzərdə tutulub. O, düzgün işləməyə bilər və ən son təhlükəsizlik və məxfilik qorumalarını ehtiva etmir. Güncəlləməni yoxlayın və ya tətbiq tərtibatçısı ilə əlaqə saxlayın."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəllənmə olmasını yoxlayın"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Bu tətbiq son Android versiyası ilə uyğun deyil. Güncəllənməni yoxlayın və ya tətbiq tərtibatçısı ilə əlaqə saxlayın."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Baxmaq üçün SMS tətbiqini açın"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Bəzi funksiyalar məhdudlaşdırıla bilər"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index f68eab66e8dd..a310cfbad129 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -86,7 +86,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ne možete da upućujete hitne pozive preko Wi‑Fi-ja"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"Obaveštenja"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status mobilnih podataka"</string>
@@ -284,7 +284,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"Obaveštenja od IT administratora"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"Obaveštenja"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozorenja"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"Režim demonstracije za maloprodajne objekte"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB veza"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova aplikacija je napravljena za stariju verziju Android-a. Možda neće raditi ispravno i ne obuhvata najnovije bezbednosne funkcije i zaštite privatnosti. Proverite da li ima ažuriranja ili se obratite programeru aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ova aplikacija nije kompatibilna sa najnovijom verzijom Android-a. Proverite da li ima ažuriranja ili se obratite programeru aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite aplikaciju za SMS da biste pregledali"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije su možda ograničene"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index a47c5b9bfdca..ad2476fa0638 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Не ўдаецца атрымаць доступ з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць тэлефон."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Гэта праграма створана для ранейшай версіі Android. Яна можа кепска працаваць, і ў ёй няма новых сродкаў абароны бяспекі і прыватнасці. Праверце наяўнасць абнаўленняў ці звярніцеся да распрацоўшчыка праграмы."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць наяўнасць абнаўленняў"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Праглядзець праз праграму для SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Функцыі могуць быць абмежаваныя"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4ed4a6601292..d2afdb2981bb 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от телефона си."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Това приложение бе създадено за по-стара версия на Android. То може да не работи правилно и не включва най-новите защити на поверителността и сигурността. Проверете за актуализация или се свържете с програмиста му."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за актуализация"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Това приложение не е съвместимо с най-новата версия на Android. Проверете за актуализация или се свържете с програмиста му."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови съобщения"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Преглед в приложението за SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Някои функции може да са ограничени"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index a034cc16ea6a..42c00f4b043b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Android-এর আরও পুরনো ভার্সনের জন্য এই অ্যাপ তৈরি করা হয়েছিল। এটি সঠিকভাবে কাজ নাও করতে পারে এবং এর মধ্যে লেটেস্ট সুরক্ষা ও গোপনীয়তার নিরাপত্তা ব্যবস্থা অন্তর্ভুক্ত করা নেই। আপডেটের জন্য চেক করুন বা অ্যাপের ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডেট পাওয়া যাচ্ছে কিনা দেখুন"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Android-এর লেটেস্ট ভার্সনের সাথে এই অ্যাপটি মানানসই নয়। আপডেটের জন্য চেক করুন বা অ্যাপ ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপনার নতুন মেসেজ আছে"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"দেখার জন্য SMS অ্যাপ্লিকেশান খুলুন"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"কিছু ফাংশন হয়ত কাজ করবে না"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"অফিসের <xliff:g id="APP">%s</xliff:g> খুলবেন?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g>-এ খুলবেন?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"অফিসের <xliff:g id="APP">%s</xliff:g>-এ খুলবেন?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"অফিসের অ্যাপ থেকে কল করবেন?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"অফিসের অ্যাপে পরিবর্তন করবেন?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে কল করার অনুমতি দেয়"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে মেসেজ পাঠানোর অনুমতি দেয়"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্রাউজার ব্যবহার করুন"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"অফিস ব্রাউজার ব্যবহার করুন"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"কল করুন"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"পরিবর্তন করুন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"সিম নেটওয়ার্ক আনলক পিন"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"সিম নেটওয়ার্ক সাবসেট আনলক পিন"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"কর্পোরেট সিম আনলক পিন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 1cb82a5b3f1e..3e5700493c1b 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -995,8 +995,8 @@
<string name="lockscreen_sim_locked_message" msgid="5911944931911850164">"SIM je zaključan."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"Otključavanje SIM-a…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
- <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Pogrešno ste unijeli svoju lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Pogrešno ste unijeli svoj PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Pogrešno ste napisali svoju lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Pogrešno ste napisali svoj PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati tablet prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put(a). U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, morat ćete otključati Android TV uređaj prijavom na svoj Google račun.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati telefon prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
@@ -1370,7 +1370,7 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Punjenje povezanog uređaja. Dodirnite za više opcija."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Otkriven je analogni periferni uređaj"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da saznate više."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"Otklanjanje grešaka putem USB-a je uspostavljeno"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"Otklanjanje grešaka putem USB-a je povezano"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Dodirnite da isključite otklanjanje grešaka putem USB-a"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Odaberite da onemogućite otklanjanje grešaka putem USB-a"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bežično otklanjanje grešaka je povezano"</string>
@@ -1668,8 +1668,8 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Pogrešno korisničko ime ili lozinka."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili lozinku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Provjeravanje računa…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Pogrešno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Pogrešno ste napisali lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Pogrešno ste nacrtali uzorak <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Pokušali ste otključati tablet na pogrešan način <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će biti vraćen na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Pokušali ste neispravno otključati Android TV uređaj <xliff:g id="NUMBER_0">%1$d</xliff:g> put(a). U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, vaš Android TV će se vratiti na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova aplikacija je izrađena za stariju verziju Androida. Možda neće pravilno funkcionirati i ne sadržava najnovije sigurnosne zaštite i zaštite privatnosti. Provjerite ima li ažuriranja ili se obratite programeru aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri je li dostupno ažuriranje"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikacija nije kompatibilna s najnovijom verzijom Androida. Provjerite ima li ažuriranja ili se obratite programeru aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije mogu biti ograničene"</string>
@@ -2166,13 +2167,13 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Otvoriti poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otvoriti u ličnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Otvoriti u poslovnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
- <string name="miniresolver_call_in_work" msgid="528779988307529039">"Želite li nazvati putem poslovne aplikacije?"</string>
- <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Želite li prebaciti na poslovnu aplikaciju?"</string>
- <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizacija dopušta upućivanje poziva samo iz poslovnih aplikacija"</string>
- <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizacija dopušta slanje poruka samo iz poslovnih aplikacija"</string>
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Pozvati iz poslovne aplikacije?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Prebaciti na poslovnu aplikaciju?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizacija vam dozvoljava da upućujete pozive samo iz poslovnih aplikacija"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizacija vam dozvoljava da šaljete poruke samo iz poslovnih aplikacija"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični preglednik"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni preglednik"</string>
- <string name="miniresolver_call" msgid="6386870060423480765">"Nazovi"</string>
+ <string name="miniresolver_call" msgid="6386870060423480765">"Pozovi"</string>
<string name="miniresolver_switch" msgid="8011924662117617451">"Prebaci"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje mreže na SIM-u"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje mrežne podgrupe na SIM-u"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4e22a1557f9a..622d648943a3 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -702,7 +702,7 @@
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No es pot crear el model facial. Torna-ho a provar."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de ser completament visible."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de veure\'s sencera."</string>
<string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S\'ha detectat una mascareta. La cara ha de veure\'s sencera."</string>
<string-array name="face_acquired_vendor">
</string-array>
@@ -996,7 +996,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"S\'està desbloquejant la targeta SIM…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el dispositiu Android TV iniciant la sessió a Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No s\'hi pot accedir des del teu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al telèfon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aquesta aplicació es va compilar per a una versió anterior d\'Android. Pot ser que no funcioni correctament i no inclou les darreres proteccions de seguretat i privadesa. Comprova si hi ha actualitzacions o contacta amb el desenvolupador de l\'aplicació."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca actualitzacions"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aquesta aplicació no és compatible amb la darrera versió d\'Android. Comprova si hi ha actualitzacions o contacta amb el desenvolupador de l\'aplicació."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tens missatges nous"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Obre l\'aplicació d\'SMS per veure\'ls"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algunes funcions poden ser limitades"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9dd2216969ad..01f4572345b6 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -270,7 +270,7 @@
<string name="global_action_settings" msgid="4671878836947494217">"Nastavení"</string>
<string name="global_action_assist" msgid="2517047220311505805">"Asistence"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"Hlas. asistence"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Zamknuto"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Zamknout"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Nové oznámení"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyzická klávesnice"</string>
@@ -631,7 +631,7 @@
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Otisk prstu se nepodařilo rozpoznat. Zkuste to znovu."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně zatlačte na snímač"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně přitiskněte na snímač"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> není k dispozici. Zkuste to na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Tato aplikace byla vytvořena pro starší verzi Androidu. Nemusí fungovat správně a neobsahuje nejnovější zabezpečení a ochranu soukromí. Zkontrolujte dostupnost aktualizace nebo kontaktujte vývojáře aplikace."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Zkontrolovat aktualizace"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Tato aplikace není kompatibilní s poslední verzí Androidu. Zkontrolujte dostupnost aktualizace nebo kontaktujte vývojáře aplikace."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové zprávy"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Zobrazíte je v aplikaci pro SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Některé funkce mohou být omezeny"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c845e72ae1d3..ebd38c89cfcf 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -684,7 +684,7 @@
<string name="face_acquired_too_high" msgid="8278815780046368576">"Løft telefonen højere op"</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"Sænk telefonen"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"Flyt telefonen længere til venstre for dig"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Flyt telefonen længere til højre for dig"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Flyt telefonen længere til højre"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Kig mere direkte på din enhed."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Dit ansigt kan ikke registreres. Hold din telefon i øjenhøjde."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Der er for meget bevægelse. Hold telefonen stille."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Du kan ikke gøre dette på din <xliff:g id="DEVICE">%1$s</xliff:g>. Prøv på din telefon i stedet."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Denne app er udviklet til en ældre version af Android. Den fungerer muligvis ikke korrekt, og den omfatter ikke de nyeste sikkerhedsfunktioner og den nyeste privatlivsbeskyttelse. Tjek, om der er en opdatering, eller kontakt appudvikleren."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Søg efter opdatering"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Denne app er ikke kompatibel med den nyeste Android-version. Tjek, om der er en opdatering, eller kontakt appudvikleren."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye beskeder"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Åbn sms-appen for at se beskeden"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Nogle funktioner er begrænsede"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 249de6e5b721..865d1b56335d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1370,7 +1370,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Analoges Audiozubehör erkannt"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Das angeschlossene Gerät ist nicht mit diesem Smartphone kompatibel. Für weitere Informationen tippen."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB-Debugging aktiviert"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Zum Deaktivieren von USB-Debugging tippen"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Zum Deaktivieren tippen"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB-Debugging deaktivieren: auswählen"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"\"Debugging über WLAN\" verbunden"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Tippen, um \"Debugging über WLAN\" zu deaktivieren"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Auf deinem <xliff:g id="DEVICE">%1$s</xliff:g> ist kein Zugriff möglich. Versuch es stattdessen auf deinem Smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Diese App wurde für eine ältere Android-Version entwickelt. Sie funktioniert möglicherweise nicht richtig und enthält nicht die neuesten Sicherheits- und Datenschutzeinstellungen. Suche nach einem Update oder wende dich an den App-Entwickler."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Auf Updates prüfen"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Diese App ist nicht mit der neuesten Android-Version kompatibel. Suche nach einem Update oder wende dich an den App-Entwickler."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du hast neue Nachrichten"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Zum Ansehen SMS-App öffnen"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funktionen sind evtl. eingeschränkt"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index a39e988bd773..7a0f5c0520e9 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Δεν είναι δυνατή η πρόσβαση σε αυτό το στοιχείο από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>. Δοκιμάστε στο τηλέφωνό σας."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Αυτή η εφαρμογή σχεδιάστηκε για μια παλαιότερη έκδοση του Android. Ενδέχεται να μην λειτουργεί σωστά και δεν περιλαμβάνει τις πιο πρόσφατες λειτουργίες ασφάλειας και προστασίας απορρήτου. Ελέγξτε αν υπάρχει διαθέσιμη μια ενημέρωση ή επικοινωνήστε με τον προγραμματιστή της εφαρμογής."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Έλεγχος για ενημέρωση"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Αυτή η εφαρμογή δεν είναι συμβατή με την πιο πρόσφατη έκδοση Android. Ελέγξτε αν υπάρχει διαθέσιμη μια ενημέρωση ή επικοινωνήστε με τον προγραμματιστή της εφαρμογής."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Έχετε νέα μηνύματα"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Άνοιγμα της εφαρμογής SMS για προβολή"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Ορισμ. λειτ. ίσως είναι περιορισμ."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b43dfb9d6d7e..725f9fa3d00a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 13b1c93333a2..86e1267eca9d 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update, or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 623f8293dd77..f0af9de9e6a9 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e79afd5870d7..2677a55b7aeb 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index a908198bfc80..fc93b3cccc43 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎This can’t be accessed on your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎. Try on your phone instead.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update, or contact the app\'s developer.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎Check for update‎‏‎‎‏‎"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.‎‏‎‎‏‎"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎You have new messages‎‏‎‎‏‎"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‎Open SMS app to view‎‏‎‎‏‎"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎Some functionality may be limited‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 433ba3851600..2bf0e3618c5c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -692,10 +692,10 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vuelve a registrar tu rostro."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"No se reconoce el rostro. Vuelve a intentarlo."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Cambia levemente la posición de la cabeza"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Quítate cualquier objeto que te cubra el rostro."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Quítate cualquier objeto que te cubra el rostro"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpia la parte superior de la pantalla, incluida la barra negra"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta app se compiló para una versión anterior de Android. Es posible que no funcione correctamente ni incluya las protecciones de la privacidad más recientes. Consulta si hay actualizaciones o comunícate con el desarrollador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Esta app no es compatible con la versión más reciente de Android. Revisa si hay actualizaciones o comunícate con el desarrollador."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abrir app de SMS para ver el mensaje"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Podrían limitarse algunas funciones"</string>
@@ -2324,7 +2325,7 @@
<string name="mic_access_on_toast" msgid="2666925317663845156">"El micrófono está disponible"</string>
<string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string>
<string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string>
- <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La Pantalla dual está activada"</string>
+ <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La función Dual Screen está activada"</string>
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está muy caliente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La Pantalla dual no está disponible porque el teléfono se está calentando demasiado"</string>
@@ -2336,7 +2337,7 @@
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%s</xliff:g>. Presiona para cambiar esta opción."</string>
<string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Presiona para cambiar esta opción."</string>
<string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
- <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiarlo."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Presiona para ver los teclados"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 03a12a0d7be4..69128d9bdd48 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -703,7 +703,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear tu modelo. Inténtalo de nuevo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Gafas oscuras detectadas. Tu cara se debe poder ver entera."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Mascarilla detectada. Tu cara se debe poder ver entera."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Cara parcialmente cubierta. Tu cara se debe poder ver entera."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"No se puede verificar. Hardware no disponible."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No se puede acceder desde tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta aplicación se creó para una versión anterior de Android. Puede que no funcione correctamente y que no incluya las protecciones de seguridad y privacidad más recientes. Comprueba si hay actualizaciones o ponte en contacto con el desarrollador de la aplicación."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualizaciones"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Esta aplicación no es compatible con la última versión de Android. Comprueba si hay actualizaciones o contacta con el desarrollador de la aplicación."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abre la aplicación de SMS para ver el mensaje"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algunas funciones limitadas"</string>
@@ -2166,8 +2167,8 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"¿Abrir <xliff:g id="APP">%s</xliff:g> de trabajo?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"¿Abrir en <xliff:g id="APP">%s</xliff:g> personal?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"¿Abrir en <xliff:g id="APP">%s</xliff:g> de trabajo?"</string>
- <string name="miniresolver_call_in_work" msgid="528779988307529039">"¿Llamar desde una aplicación de trabajo?"</string>
- <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"¿Cambiar a una aplicación de trabajo?"</string>
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"¿Llamar desde la aplicación de trabajo?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"¿Cambiar a la aplicación de trabajo?"</string>
<string name="miniresolver_call_information" msgid="6739417525304184083">"Tu organización solo te permite hacer llamadas desde aplicaciones de trabajo"</string>
<string name="miniresolver_sms_information" msgid="4311292661329483088">"Tu organización solo te permite enviar mensajes desde aplicaciones de trabajo"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador personal"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 01b8833e548d..b58639fba6d9 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SEES"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VÄLJAS"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Kas anda teenusele <xliff:g id="SERVICE">%1$s</xliff:g> teie seadme üle täielik kontroll?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik haldusõigus sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik kontroll sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekraanikuva vaatamine ja haldamine"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"See saab lugeda kogu ekraanil kuvatud sisu ja kuvada sisu rakenduste peal."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Toimingute vaatamine ja tegemine"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Sellele ei pääse teie seadmes <xliff:g id="DEVICE">%1$s</xliff:g> juurde. Proovige juurde pääseda oma telefonis."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"See rakendus on loodud Androidi vanema versiooni jaoks. See ei pruugi õigesti töötada ega hõlma uusimaid turva- ja privaatsusfunktsioone. Otsige värskendust või võtke ühendust rakenduse arendajaga."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Otsi värskendust"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"See rakendus ei ühildu Androidi uusima versiooniga. Otsige värskendust või võtke ühendust rakenduse arendajaga."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Teile on uusi sõnumeid"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Avage vaatamiseks SMS-rakendus"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Mõned funkts. võivad olla piiratud"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Kas avada töörakendus <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Kas avada isiklikus rakenduses <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Kas avada töörakenduses <xliff:g id="APP">%s</xliff:g>?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Kas helistada töörakendusest?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Kas lülituda töörakendusele?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Teie organisatsioon lubab helistada ainult töörakendustest."</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Teie organisatsioon lubab sõnumeid saata ainult töörakendustest."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kasuta isiklikku brauserit"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Kasuta tööbrauserit"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Helistage"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Lülitu"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kaardi võrgu avamise PIN-kood"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM-kaardi võrgu alamhulga avamise PIN-kood"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-kaardi ettevõtte avamise PIN-kood"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 389398585eec..f14a0070177f 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -47,8 +47,8 @@
<string name="needPuk2" msgid="3910763547447344963">"Idatzi PUK2-a SIMa desblokeatzeko."</string>
<string name="enablePin" msgid="2543771964137091212">"Ezin izan da aldatu. Gaitu SIM edo RUIM txartelaren blokeoa."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela blokeatu aurretik.</item>
- <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela blokeatu aurretik.</item>
+ <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIMa blokeatu aurretik.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIMa blokeatu aurretik.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEIa"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
@@ -80,7 +80,7 @@
<string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Ez dago ahots-deien zerbitzurik"</string>
<string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Ez dago ahozko zerbitzurik eta ezin da egin larrialdi-deirik"</string>
<string name="RestrictedStateContent" msgid="7693575344608618926">"Operadoreak desaktibatu egin du aldi baterako"</string>
- <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operadoreak <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela desaktibatu egin du aldi baterako"</string>
+ <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operadoreak <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa desaktibatu egin du aldi baterako"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ezin da konektatu sare mugikorrera"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Aldatu sare hobetsia. Sakatu aldatzeko."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ezin da egin larrialdi-deirik"</string>
@@ -459,7 +459,7 @@
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Aplikazioak deien historia irakur dezake."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"idatzi deien erregistroan"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tabletaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV gailuko deien erregistroa aldatzeko baimena ematen die aplikazioei, jasotako eta egindako deiei buruzko datuak barne. Baliteke asmo txarreko aplikazioek deien erregistroa ezabatzea edo aldatzea."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV gailuko deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Baliteke asmo txarreko aplikazioek deien erregistroa ezabatzea edo aldatzea."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Telefonoaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
<string name="permlab_bodySensors" msgid="662918578601619569">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa erabili bitartean"</string>
<string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikazioak erabiltzen diren bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) erabiltzeko baimena ematen die aplikazio horiei."</string>
@@ -979,7 +979,7 @@
<string name="lockscreen_missing_sim_instructions" msgid="5823469004536805423">"Gehitu SIM bat."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="4403843937236648032">"SIMa falta da, edo ezin da irakurri. Gehitu SIM bat."</string>
<string name="lockscreen_permanent_disabled_sim_message_short" msgid="1925200607820809677">"Ezin da erabili SIMa."</string>
- <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Betiko desaktibatu da SIMa.\n Jarri harremanetan operadorearekin beste SIM bat eskuratzeko."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Betiko desaktibatu da SIMa.\n Jarri operadorearekin harremanetan beste SIM bat eskuratzeko."</string>
<string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Aurreko pista"</string>
<string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Hurrengo pista"</string>
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pausatu"</string>
@@ -1044,7 +1044,7 @@
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzea."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN kodearen bidez desblokeatzea."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIMa desblokeatzeko PINa."</string>
- <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM txartela desblokeatzeko PUK kodea."</string>
+ <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIMa desblokeatzeko PUK kodea."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Pasahitzaren bidez desblokeatzea."</string>
<string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Eredua marrazteko eremua."</string>
<string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Hatza lerratzeko eremua."</string>
@@ -1926,9 +1926,9 @@
<string name="call_notification_answer_video_action" msgid="2086030940195382249">"Bideoa"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Baztertu"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Amaitu deia"</string>
- <string name="call_notification_incoming_text" msgid="6143109825406638201">"Jasotako deia"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Sarrerako deia"</string>
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
- <string name="call_notification_screening_text" msgid="8396931408268940208">"Jasotako dei bat bistaratzen"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Sarrerako dei bat bistaratzen"</string>
<string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriarik gabea"</string>
<string name="importance_from_user" msgid="2782756722448800447">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
<string name="importance_from_person" msgid="4235804979664465383">"Garrantzitsua da eragiten dien pertsonengatik."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili telefonoa."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Android-en bertsio zaharrago baterako sortu da aplikazio hau. Baliteke behar bezala ez funtzionatzea, eta ez ditu barne hartzen azken segurtasun- eta pribatutasun-babesak. Begiratu ea eguneratzerik dagoen edo jarri aplikazioaren garatzailearekin harremanetan."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Bilatu eguneratzeak"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikazio hau ez da Androiden azken bertsioarekin bateragarria. Begiratu ea eguneratzerik dagoen edo jarri aplikazioaren garatzailearekin harremanetan."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mezu berriak dituzu"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Mezuak ikusteko, ireki SMSetarako aplikazioa"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Baliteke funtzio batzuk mugatuta egotea"</string>
@@ -2044,14 +2045,14 @@
<string name="etws_primary_default_message_test" msgid="4583367373909549421">"Larrialdi-mezuen proba"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Erantzun"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
- <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
- <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM txartela ez dago hornituta ahotsa erabiltzeko"</string>
+ <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIMa ezin da erabili ahotsa erabiltzeko"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIMa ez dago hornituta ahotsa erabiltzeko"</string>
<string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
<string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefonoa ezin da erabili ahotsa erabiltzeko"</string>
- <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
+ <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ez da onartzen <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
<string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIMik"</string>
- <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
- <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
+ <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
+ <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
<string name="popup_window_default_title" msgid="6907717596694826919">"Leiho gainerakorra"</string>
<string name="slice_more_content" msgid="3377367737876888459">"Beste <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Aplikazioaren bertsio zaharrago batera aldatu da, edo aplikazioa ez da lasterbide honekin bateragarria"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Laneko <xliff:g id="APP">%s</xliff:g> aplikazioan ireki nahi duzu?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> pertsonalean ireki nahi duzu?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Laneko <xliff:g id="APP">%s</xliff:g> aplikazioan ireki nahi duzu?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Laneko aplikaziotik deitu nahi duzu?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Laneko aplikaziora aldatu nahi duzu?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Laneko aplikazioetatik soilik deitzeko baimena ematen du zure erakundeak"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Mezuak laneko aplikazioetatik soilik bidaltzeko baimena ematen du zure erakundeak"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Erabili arakatzaile pertsonala"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Erabili laneko arakatzailea"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Deitu"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Aldatu"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIMaren sarearen bidez desblokeatzeko PINa"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIMaren sareko azpimultzoaren bidez desblokeatzeko PINa"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Enpresaren SIMaren bidez desblokeatzeko PINa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 415dce575740..2a77aa2cb947 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"نمی‌توان در <xliff:g id="DEVICE">%1$s</xliff:g> به این مورد دسترسی داشت. دسترسی به آن را در تلفنتان امتحان کنید."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏این برنامه برای نسخه قدیمی‌تری از Android ساخته شده است. احتمال دارد به‌درستی کار نکند و شامل جدیدترین محافظت‌های حریم خصوصی و امنیت نمی‌شود. بررسی کنید به‌روزرسانی دردسترس باشد یا با توسعه‌دهنده برنامه تماس بگیرید."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"بررسی وجود به‌روزرسانی"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"پیام‌های جدیدی دارید"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"برای مشاهده، برنامه پیامک را باز کنید"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"برخی از عملکردها ممکن است محدود باشند"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index ccca9df10fac..a5a0a3f7d9b3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> ei saa pääsyä sovellukseen. Kokeile striimausta puhelimella."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle. Se ei välttämättä toimi oikein eikä sisällä uusimpia tietoturvan ja yksityisyyden suojauksia. Tarkista päivitykset tai ota yhteyttä sovelluksen kehittäjään."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tarkista päivitykset"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Sovellus ei ole yhteensopiva uusimman Android-version kanssa. Tarkista päivitykset tai ota yhteyttä sovelluksen kehittäjään."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sinulle on uusia viestejä"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Katso avaamalla tekstiviestisovellus."</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Osaa toiminnoista voidaan rajoittaa"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 6bc290fd8c82..a7803784af96 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -506,8 +506,7 @@
<string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
<string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder au mode vibration."</string>
<string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
- <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
- <skip />
+ <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'application à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"voir l\'état et l\'identité du téléphone"</string>
@@ -1977,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre téléphone à la place."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette application a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'application."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctionnalités sont limitées"</string>
@@ -2160,29 +2161,21 @@
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
- <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
- <skip />
- <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
- <skip />
+ <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applications professionnelles sont interrompues"</string>
+ <string name="resolver_switch_on_work" msgid="4527096360772311894">"Réactiver"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
<string name="miniresolver_open_work" msgid="6286176185835401931">"Ouvrir le profil professionnel de <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil personnel?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil professionnel?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'application professionnelle?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'application professionnelle?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applications professionnelles"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur du profil personnel"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur du profil professionnel"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Appeler"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Changer"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"NIP de déverrouillage du réseau associé au module SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"NIP de déverrouillage du sous-ensemble du réseau associé au module SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"NIP de déverrouillage du module SIM professionnel"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 71749bb8a73e..f80373d07f01 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -626,11 +626,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Utilisez le verrouillage de l\'écran pour continuer"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez bien sur le lecteur"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez fermement sur le lecteur"</string>
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Impossible de reconnaître l\'empreinte digitale. Réessayez."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le lecteur d\'empreinte digitale et réessayez"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le lecteur et réessayez"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez bien sur le lecteur"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez fermement sur le lecteur"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
@@ -1698,9 +1698,9 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉE"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Accorder le contrôle total de votre appareil à <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des autres applications."</string>
- <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et contrôler l\'écran"</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Voir et contrôler l\'écran"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Le service peut lire l\'intégralité du contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Afficher et effectuer des actions"</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Voir et effectuer des actions"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Le service peut suivre vos interactions avec une application ou un capteur matériel, et interagir avec des applications de votre part."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ces paramètres sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt sur votre téléphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette appli a été conçue pour une ancienne version d\'Android. Elle risque de ne pas fonctionner correctement et n\'inclut pas les derniers dispositifs de sécurité et de protection de la confidentialité. Recherchez une mise à jour ou contactez le développeur de l\'appli."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rechercher une mise à jour"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Cette appli n\'est pas compatible avec la dernière version d\'Android. Recherchez une mise à jour ou contactez le développeur de l\'appli."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrir l\'application de SMS pour afficher le message"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctions peuvent être limitées"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 5e791fd45f7b..db56bfd6b9d5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -312,7 +312,7 @@
<string name="permgroupdesc_storage" msgid="5378659041354582769">"acceder a ficheiros no teu dispositivo"</string>
<string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e audio"</string>
<string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acceder a música e audio do dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"fotos e vídeos"</string>
<string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acceder a fotos e vídeos do dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar audio"</string>
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Non se puido crear o modelo facial. Téntao de novo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Levas lentes escuras, pero débeseche ver toda a cara"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Levas máscara, pero débeseche ver toda a cara"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Tes a cara tapada, pero débeseche ver enteira"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Sen verificar a cara. Hardware non dispoñible."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non se puido acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta aplicación deseñouse para unha versión anterior de Android. Quizais non funcione correctamente e non inclúa as últimas medidas de protección de privacidade e seguranza. Comproba se hai actualizacións ou ponte en contacto co programador da aplicación."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tes mensaxes novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abre a aplicación de SMS para ver as mensaxes"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Pode haber funcións limitadas"</string>
@@ -2165,20 +2167,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Queres abrir a aplicación <xliff:g id="APP">%s</xliff:g> do traballo?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Queres abrir o contido na aplicación <xliff:g id="APP">%s</xliff:g> persoal?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Queres abrir o contido na aplicación <xliff:g id="APP">%s</xliff:g> do traballo?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Queres chamar desde a aplicación do traballo?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Queres cambiar á aplicación do traballo?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"A túa organización só che permite chamar desde aplicacións do traballo"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"A túa organización só che permite enviar mensaxes desde aplicacións do traballo"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utilizar navegador persoal"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utilizar navegador de traballo"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Chamar"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Cambiar"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo da rede SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo do subconxunto da rede SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo da SIM"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 41d09d924d57..12f43d288700 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"આને તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પર ઍક્સેસ કરી શકાતી નથી. તેના બદલે તમારા ફોન પર પ્રયાસ કરો."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Androidના કોઈ જૂના વર્ઝન માટે આ ઍપ બનાવવામાં આવી હતી. તે કદાચ યોગ્ય રીતે કામ કરતી નથી અને તેમાં નવીનતમ સુરક્ષા અને પ્રાઇવસી સંબંધિત સંરક્ષણો શામેલ નથી. કોઈ અપડેટ ચેક કરો અથવા ઍપના ડેવલપરનો સંપર્ક કરો."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"અપડેટ માટે તપાસો"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"તમારી પાસે નવા સંદેશા છે"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"જોવા માટે SMS ઍપ્લિકેશન ખોલો"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"કેટલીક કાર્યક્ષમતા મર્યાદિત હોઈ શકે છે"</string>
@@ -2165,20 +2167,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ઑફિસની પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g> ખોલીએ?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"વ્યક્તિગત પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ઑફિસની પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"શું ઑફિસ માટેની ઍપમાંથી કૉલ કરીએ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"શું ઑફિસ માટેની ઍપ પર સ્વિચ કરીએ?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી કૉલ કરવાની મંજૂરી આપે છે"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી મેસેજ મોકલવાની મંજૂરી આપે છે"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"વ્યક્તિગત બ્રાઉઝરનો ઉપયોગ કરો"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ઑફિસના બ્રાઉઝરના ઉપયોગ કરો"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"કૉલ કરો"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"સ્વિચ કરો"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"સિમ નેટવર્કને અનલૉક કરવાનો પિન"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"સિમ નેટવર્ક સબસેટને અનલૉક કરવાનો પિન"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"સિમ કૉર્પોરેટ કાર્ડના લૉકને અનલૉક કરવાનો પિન"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c750d50fb729..9ebe4f70c3e1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> पर इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने फ़ोन पर ऐक्सेस करने की कोशिश करें."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"यह ऐप्लिकेशन, Android के पुराने वर्शन के लिए बनाया गया था. इसमें सिक्योरिटी और निजता सुरक्षा से जुड़ी नई सुविधाएं शामिल नहीं हैं. साथ ही, ऐसा हो सकता है कि यह ठीक से काम न करे. अपडेट के बारे में पता करें या ऐप्लिकेशन के डेवलपर से संपर्क करें."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"देखें कि अपडेट मौजूद है या नहीं"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"यह ऐप्लिकेशन, Android के सबसे नए वर्शन पर काम नहीं करता है. अपडेट के बारे में पता करें या ऐप्लिकेशन के डेवलपर से संपर्क करें."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपके पास नए संदेश हैं"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"देखने के लिए मैसेज (एसएमएस) ऐप खोलें"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"शायद कुछ सुविधाएं काम न करें"</string>
@@ -2166,7 +2167,7 @@
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"निजी प्रोफ़ाइल वाले <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन में जाकर खोलें?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"वर्क प्रोफ़ाइल वाले <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन में जाकर खोलें?"</string>
<string name="miniresolver_call_in_work" msgid="528779988307529039">"क्या आपको वर्क ऐप्लिकेशन से कॉल करना है?"</string>
- <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"क्या आपको वर्क ऐप्लिकेशन में स्विच करना है?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"क्या आपको वर्क ऐप्लिकेशन पर स्विच करना है?"</string>
<string name="miniresolver_call_information" msgid="6739417525304184083">"आपके संगठन ने, सिर्फ़ वर्क ऐप्लिकेशन से कॉल करने की अनुमति दी है"</string>
<string name="miniresolver_sms_information" msgid="4311292661329483088">"आपके संगठन ने, सिर्फ़ वर्क ऐप्लिकेशन से मैसेज भेजने की अनुमति दी है"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"निजी ब्राउज़र का इस्तेमाल करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 38d3f01be2ff..6bf82308276b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -996,7 +996,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"Otključavanje SIM-a…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> zamolit ćemo vas da otključate Android TV uređaj putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati telefon putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
@@ -1668,7 +1668,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Nevažeće korisničko ime ili zaporka."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Provjera računa..."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova je aplikacija razvijena za stariju verziju Androida. Možda neće funkcionirati pravilno i ne uključuje najnovije zaštite sigurnosti i privatnosti. Provjerite je li za tu aplikaciju dostupno ažuriranje ili se obratite razvojnom programeru."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri ažuriranja"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funkcije mogu biti ograničene"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0525338b4abd..38fd4ac989a2 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ehhez nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a telefonon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ez az alkalmazás az Android egy korábbi verziójához készült. Előfordulhat, hogy nem működik megfelelően, és nem tartalmazza a legfrissebb biztonsági és adatvédelmi megoldásokat. Keressen frissítést, vagy forduljon az app fejlesztőjéhez."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Frissítés keresése"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ez az alkalmazás nem kompatibilis az Android legújabb verziójával. Keressen frissítést, vagy forduljon az app fejlesztőjéhez."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Új üzenetei érkeztek"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"SMS-alkalmazás megnyitása a megtekintéshez"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Egyes funkciók korlátozva lehetnek"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index db5acb9349dd..e158faa6fbc5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Այս գործառույթը հասանելի չէ <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Օգտագործեք ձեր հեռախոսը։"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Այս հավելվածը մշակված է Android-ի ավելի հին տարբերակի համար։ Այն չի համապատասխանում անվտանգության և գաղտնիության ապահովման վերջին պահանջներին և կարող է պատշաճ կերպով չաշխատել։ Ստուգեք թարմացումների առկայությունը կամ դիմեք հավելվածի մշակողին։"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Այս հավելվածը համատեղելի չէ Android-ի վերջին տարբերակի հետ։ Ստուգեք թարմացումների առկայությունը կամ դիմեք հավելվածը մշակողին։"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS-ների փոխանակման հավելվածը"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Որոշ գործառույթներ կարող են չաշխատել"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4609fdf0301f..c854e12fa4e3 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -475,7 +475,7 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Aplikasi ini dapat menambahkan, menghapus, atau mengubah acara kalender di ponsel. Aplikasi ini dapat mengirim pesan yang kelihatannya berasal dari pemilik kalender, atau mengubah acara tanpa memberi tahu pemilik."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"akses perintah penyedia lokasi ekstra"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Memungkinkan aplikasi mengakses perintah penyedia lokasi ekstra. Tindakan ini memungkinkan aplikasi mengganggu pengoperasian GPS atau sumber lokasi lain."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi akurat hanya saat di latar depan"</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi presisi hanya saat di latar depan"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Aplikasi ini bisa mendapatkan lokasi pasti Anda dari layanan lokasi saat aplikasi sedang digunakan. Layanan lokasi untuk perangkat harus diaktifkan agar aplikasi bisa mendapatkan lokasi. Ini dapat meningkatkan penggunaan baterai."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"akses perkiraan lokasi hanya saat berada di latar depan"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Aplikasi ini bisa mendapatkan perkiraan lokasi Anda dari layanan lokasi saat aplikasi sedang digunakan. Layanan lokasi untuk perangkat harus diaktifkan agar aplikasi bisa mendapatkan lokasi."</string>
@@ -1695,7 +1695,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Jangan aktifkan"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIF"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NONAKTIF"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> memiliki kontrol penuh atas perangkat Anda?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> mengontrol perangkat Anda secara penuh?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang mendukung kebutuhan aksesibilitas Anda, tetapi tidak untuk sebagian besar aplikasi."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengontrol layar"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Voice Access dapat membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di ponsel."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplikasi ini dibuat untuk versi lama Android. Aplikasi mungkin tidak berfungsi dengan baik dan tidak menyertakan perlindungan privasi dan keamanan terbaru. Periksa update, atau hubungi developer aplikasi."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikasi ini tidak kompatibel dengan versi terbaru Android. Periksa update atau hubungi developer aplikasi."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buka aplikasi SMS untuk melihat"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Beberapa fitur tidak dapat digunakan"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 30f0bd988f70..1c7a07df45a8 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ekki er hægt að opna þetta í <xliff:g id="DEVICE">%1$s</xliff:g>. Prófaðu það í símanum í staðinn."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Þetta forrit var hannað fyrir eldri útgáfu af Android. Óvíst er að það virki rétt og það inniheldur ekki nýjustu öryggis- og persónuverndarvarnirnar. Leitaðu að uppfærslu eða hafðu samband við þróunaraðila forritsins."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Leita að uppfærslu"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Þetta forrit er ekki samhæft nýjustu útgáfu Android. Athugaðu hvort uppfærsla sé í boði eða hafðu samband við þróunaraðila forritsins."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Þú ert með ný skilaboð"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Opnaðu SMS-forritið til að skoða"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sum virkni kann að vera takmörkuð"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 45f4792b8fc9..2e9d1ec2158c 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -682,12 +682,12 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"Luce insufficiente"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"Allontana il telefono"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"Avvicina il telefono"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta il telefono più in alto"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta il telefono più in basso"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono verso sinistra"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono verso destra"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta lo smartphone più in alto"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta lo smartphone più in basso"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta lo smartphone verso sinistra"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta lo smartphone verso destra"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Guarda più direttamente verso il dispositivo."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Impossibile vedere il volto. Tieni il telefono all\'altezza degli occhi"</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Volto non visible. Tieni lo smartphone all\'altezza degli occhi."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Troppo movimento. Tieni fermo il telefono."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ripeti l\'acquisizione del volto."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Impossibile riconoscere il volto. Riprova."</string>
@@ -1716,7 +1716,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"Correzione del colore"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modalità a una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Apparecchi acustici"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Protesi uditive"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Questa app è stata progettata per una versione precedente di Android. Potrebbe non funzionare correttamente e non include le protezioni della sicurezza e della privacy più recenti. Verifica la presenza di un aggiornamento o contatta lo sviluppatore dell\'app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca aggiornamenti"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Questa app non è compatibile con la versione più recente di Android. Verifica la presenza di un aggiornamento o contatta lo sviluppatore dell\'app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Apri l\'app SMS per la visualizzazione"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Alcune funzionalità sono limitate"</string>
@@ -2166,20 +2167,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Aprire l\'app <xliff:g id="APP">%s</xliff:g> di lavoro?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Aprire nell\'app <xliff:g id="APP">%s</xliff:g> personale?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Aprire nell\'app <xliff:g id="APP">%s</xliff:g> di lavoro?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Chiamare dall\'app di lavoro?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vuoi passare all\'app di lavoro?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"La tua organizzazione consente di fare chiamate solo dalle app di lavoro"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"La tua organizzazione consente di inviare messaggi solo dalle app di lavoro"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usa il browser personale"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usa il browser di lavoro"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Chiama"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Passa"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN di sblocco rete SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN di sblocco sottoinsieme rete SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN sblocco aziendale SIM"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6b7ede25171d..50685cb5994f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1371,7 +1371,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"‏ניפוי באגים ב-USB מחובר"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"‏לכיבוי של ניפוי הבאגים ב-USB, יש להקיש"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"‏יש ללחוץ על ההתראה כדי להשבית ניפוי באגים ב-USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ניפוי הבאגים האלחוטי מחובר"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string>
@@ -1696,8 +1696,8 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"לא להפעיל"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"מופעל"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"כבוי"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"להעניק לשירות <xliff:g id="SERVICE">%1$s</xliff:g> שליטה מלאה במכשיר?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"האפשרות לשליטה מלאה במכשיר לא מתאימה לכל האפליקציות, אלא רק לאפליקציות שעוזרות עם צורכי הנגישות שלך."</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"להעניק לשירות \'<xliff:g id="SERVICE">%1$s</xliff:g>\' שליטה מלאה במכשיר?"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"האפשרות לשליטה מלאה במכשיר לא מתאימה לרוב האפליקציות, אלא רק לאפליקציות שעוזרות עם צורכי הנגישות שלך."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"הצגת המסך ושליטה בו"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"אפשרות לקריאת כל התוכן במסך ולהצגת התוכן מעל אפליקציות אחרות."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"הצגה וביצוע של פעולות"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"אי אפשר לגשת להגדרה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g>. במקום זאת, אפשר לנסות בטלפון."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏האפליקציה הזו תוכננה לגרסה ישנה יותר של Android. האפליקציה לא כוללת את אמצעי ההגנה האחרונים לאבטחה ופרטיות, ועלולה לא לעבוד כראוי. כדאי לבדוק אם יש עדכון או ליצור קשר עם מפתח האפליקציה."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"יש עדכון חדש?"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"‏האפליקציה הזו לא תואמת לגרסה העדכנית של Android. כדאי לבדוק אם יש עדכון או ליצור קשר עם מפתחי האפליקציה."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"יש לך הודעות חדשות"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏יש לפתוח את אפליקציית ה-SMS כדי להציג"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ייתכן שחלק מהפונקציונליות תהיה מוגבלת"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 496aaa30557c..dc4694d03bed 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -648,8 +648,8 @@
<string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋の設定がタイムアウトしました。もう一度お試しください。"</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"指紋の操作がユーザーによりキャンセルされました。"</string>
- <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
- <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
+ <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに PIN を入力してください。"</string>
+ <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに PIN を入力してください。"</string>
<string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"指紋を処理できません。もう一度お試しください。"</string>
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> からはアクセスできません。スマートフォンでのアクセスをお試しください。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"このアプリは Android の以前のバージョンを対象としているため、正しく動作しない可能性があります。最新のセキュリティ保護やプライバシー保護は組み込まれていません。アップデートをご確認いただくか、アプリのデベロッパーにお問い合わせください。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"アップデートを確認"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"このアプリは最新バージョンの Android に対応していません。アップデートをご確認いただくか、アプリのデベロッパーにお問い合わせください。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"新着メッセージがあります"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"表示するには SMS アプリを開きます"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"一部の機能が制限されることがあります"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 42e9b695d78b..f4d391bfbcba 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1950,8 +1950,8 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ამჟამად მიუწვდომელია. ის იმართება <xliff:g id="APP_NAME_1">%2$s</xliff:g>-ის მიერ."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"შეიტყვეთ მეტი"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"აპის დაპაუზების გაუქმება"</string>
- <string name="work_mode_off_title" msgid="6367463960165135829">"გაუქმდეს სამსახურის აპების დაპაუზება?"</string>
- <string name="work_mode_turn_on" msgid="5316648862401307800">"პაუზის გაუქმება"</string>
+ <string name="work_mode_off_title" msgid="6367463960165135829">"კვლავ გააქტიურდეს სამსახურის აპები?"</string>
+ <string name="work_mode_turn_on" msgid="5316648862401307800">"გააქტიურება"</string>
<string name="work_mode_emergency_call_button" msgid="6818855962881612322">"საგანგებო სიტუაცია"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ამჟამად მიუწვდომელია."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტელეფონიდან."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა. ის შესაძლოა არ მიშაობდეს სწორად და არ შეიცავდეს უსაფრთხოებისა და კონფიდენციალურობის უახლეს დაცვას. შეამოწმეთ განახლება, ან დაუკავშირდით აპის დეველოპერს."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"განახლების შემოწმება"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ეს აპი არ არის თავსებადი Android-ის უახლეს ვერსიასთან. შეამოწმეთ განახლება, ან დაუკავშირდით აპის დეველოპერს."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"თქვენ ახალი შეტყობინებები გაქვთ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"სანახავად, გახსენით SMS აპი"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ზოგიერთი ფუნქცია შეიძლება შეიზღუდოს"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"გსურთ, სამსახურის <xliff:g id="APP">%s</xliff:g>-ის გახსნა?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"გსურთ, პირად <xliff:g id="APP">%s</xliff:g>-ში გახსნა?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"გსურთ, სამსახურის <xliff:g id="APP">%s</xliff:g>-ში გახსნა?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"სამსახურის აპიდან დარეკავთ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"გადაერთვებით სამუშაო აპზე?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"თქვენი ორგანიზაცია ნებას გრთავთ, რომ დარეკოთ მხოლოდ სამსახურის აპებიდან"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"თქვენი ორგანიზაცია ნებას გრთავთ, მხოლოდ სამსახურის აპებიდან გაგზავნოთ შეტყობინებები"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"პირადი ბრაუზერის გამოყენება"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"სამსახურის ბრაუზერის გამოყენება"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"ზარი"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"გადართვა"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ქსელის განბლოკვის PIN-კოდი"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ქსელის ქვედანაყოფის განბლოკვის PIN-კოდი"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-ის კორპორატიული განბლოკვის PIN-კოდი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index fe4bb54b71ea..03897c1e90f7 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына телефонды пайдаланып көріңіз."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Бұл қолданба Android жүйесінің ескі нұсқасына арналған. Ол дұрыс жұмыс істемеуі және онда соңғы қауіпсіздік пен құпиялықты сақтау құралдары болмауы мүмкін. Қолданбаның жаңа нұсқасы бар-жоғын тексеріңіз не оны әзірлеушіге хабарласыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңарту бар-жоғын тексеру"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Бұл қолданба Android-тың соңғы нұсқасымен үйлесімді емес. Қолданбаның жаңа нұсқасы бар-жоғын тексеріңіз не әзірлеушіге хабарласыңыз."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сізде жаңа хабарлар бар"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Көру үшін SMS қолданбасын ашыңыз"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Кейбір функциялар істемеуі мүмкін."</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"<xliff:g id="APP">%s</xliff:g> қолданбасы жұмыс профилімен ашылсын ба?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> қолданбасындағы жеке профильден ашылсын ба?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"<xliff:g id="APP">%s</xliff:g> қолданбасындағы жұмыс профилінен ашылсын ба?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Жұмыс қолданбасынан қоңырау шалу керек пе?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Жұмыс қолданбасына ауысу керек пе?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Ұйымыңыз тек жұмыс қолданбаларынан қоңырау шалуға рұқсат етеді."</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ұйымыңыз тек жұмыс қолданбаларынан хабар жіберуге рұқсат етеді."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке браузерді пайдалану"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жұмыс браузерін пайдалану"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Қоңырау шалу"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Ауысу"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM желісінің құлпын ашатын PIN коды"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM желісі ішкі жиынтығының құлпын ашатын PIN коды"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Корпоративтік SIM картасының құлпын ашатын PIN коды"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5f817353df4b..b4c746e03738 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -656,7 +656,7 @@
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
<string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើ​ឧបករណ៍ចាប់ស្នាមម្រាមដៃ​បានទេ។ សូមទាក់ទង​ក្រុមហ៊ុនផ្ដល់​ការជួសជុល"</string>
<string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"បាន​ចុច​ប៊ូតុង​ថាមពល"</string>
- <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃទី <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
<string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើ​ស្នាមម្រាមដៃ​របស់អ្នក ដើម្បីបន្ត"</string>
@@ -665,10 +665,10 @@
</string-array>
<string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ដោះ​សោ​តាម​​ទម្រង់​មុខ"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ការដោះ​សោ​ដោយស្កេន​មុខ"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"មានបញ្ហា​ពាក់ព័ន្ធនឹង​មុខងារ​ដោះសោ​តាមទម្រង់មុខ"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ចុចដើម្បីលុប​គំរូមុខ​របស់អ្នក រួចបញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
- <string name="face_setup_notification_title" msgid="8843461561970741790">"រៀបចំ​ការដោះសោ​តាមទម្រង់មុខ"</string>
+ <string name="face_setup_notification_title" msgid="8843461561970741790">"រៀបចំ​ការដោះសោ​ដោយស្កេនមុខ"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"ដោះសោទូរសព្ទ​របស់អ្នកដោយសម្លឹងមើលវា"</string>
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"ដើម្បីប្រើមុខងារដោះសោតាមទម្រង់មុខ សូមបើក"<b>"ការចូលប្រើកាមេរ៉ា"</b>"នៅក្នុងការកំណត់ &gt; ឯកជនភាព"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"រៀបចំ​វិធីច្រើនទៀត​ដើម្បី​ដោះសោ"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"មិនអាច​ចូលប្រើប្រាស់​កម្មវិធី​នេះ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបាន​ទេ។ សូមសាកល្បងប្រើ​នៅលើ​ទូរសព្ទរបស់អ្នក​ជំនួសវិញ។"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"កម្មវិធីនេះ​ត្រូវបានបង្កើតឡើង​សម្រាប់​កំណែ Android ចាស់​ជាងនេះ។ កម្មវិធីនេះអាចមិនដំណើរការបានត្រឹមត្រូវ និងមិនរួមបញ្ចូលការការពារឯកជនភាព និងសុវត្ថិភាពចុងក្រោយបំផុតទេ។ ពិនិត្យរកមើលកំណែថ្មី ឬទាក់ទងទៅអ្នកអភិវឌ្ឍន៍កម្មវិធី។"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"រក​មើល​កំណែ​ថ្មី"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"កម្មវិធីនេះ​មិនត្រូវគ្នាជាមួយ​កំណែ Android ចុងក្រោយបំផុត​ទេ។ សូមពិនិត្យរកមើល​កំណែថ្មី ឬទាក់ទងទៅ​អ្នកអភិវឌ្ឍន៍កម្មវិធី។"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"អ្នកមានសារថ្មី"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"បើកកម្មវិធីសារ SMS ដើម្បីមើល"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"មុខងារ​មួយចំនួន​អាច​ត្រូវ​បាន​កម្រិត"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 9342fad034d2..55a0a8430122 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -66,7 +66,7 @@
<string name="ThreeWCMmi" msgid="2436550866139999411">"ಮೂರು ಮಾರ್ಗದಲ್ಲಿ ಕರೆ ಮಾಡುವಿಕೆ"</string>
<string name="RuacMmi" msgid="1876047385848991110">"ಅನಪೇಕ್ಷಿತ ಕಿರಿಕಿರಿ ಮಾಡುವ ಕರೆಗಳ ತಿರಸ್ಕಾರ"</string>
<string name="CndMmi" msgid="185136449405618437">"ಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆಯ ಡೆಲಿವರಿ"</string>
- <string name="DndMmi" msgid="8797375819689129800">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
+ <string name="DndMmi" msgid="8797375819689129800">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಿಲ್ಲ"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸದಿರುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
@@ -270,7 +270,7 @@
<string name="global_action_voice_assist" msgid="6655788068555086695">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="global_action_lockdown" msgid="2475471405907902963">"ಲಾಕ್‌ಡೌನ್‌"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
- <string name="notification_hidden_text" msgid="2835519769868187223">"ಹೊಸ ಅಧಿಸೂಚನೆ"</string>
+ <string name="notification_hidden_text" msgid="2835519769868187223">"ಹೊಸ ನೋಟಿಫಿಕೇಶನ್‍"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"ಭದ್ರತೆ"</string>
<string name="notification_channel_car_mode" msgid="2123919247040988436">"ಕಾರ್ ಮೋಡ್"</string>
@@ -471,7 +471,7 @@
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"ಮಾಲೀಕರ ಗಮನಕ್ಕೆ ತರದೆಯೇ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ ಅಥವಾ ಮಾರ್ಪಡಿಸಿ ಮತ್ತು ಅತಿಥಿಗಳಿಗೆ ಇಮೇಲ್ ಕಳುಹಿಸಿ"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬಂದಿರಬಹುದಾದ ಕಾಣಿಸಿಕೊಳ್ಳುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅವರ ಮಾಲೀಕರಿಗೆ ತಿಳಿಸದಂತೆ ಘಟನೆಗಳು ಬದಲಾಯಿಸುವುದು."</string>
- <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬರುವಂತೆ ಕಾಣುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅದರ ಮಾಲೀಕರಿಗೆ ಅಧಿಸೂಚನೆ ನೀಡದೆ ಈವೆಂಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
+ <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬರುವಂತೆ ಕಾಣುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅದರ ಮಾಲೀಕರಿಗೆ ನೋಟಿಫಿಕೇಶನ್ ನೀಡದೆ ಈವೆಂಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬಂದಿರಬಹುದಾದ ಕಾಣಿಸಿಕೊಳ್ಳುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅವರ ಮಾಲೀಕರಿಗೆ ತಿಳಿಸದಂತೆ ಘಟನೆಗಳು ಬದಲಾಯಿಸುವುದು."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ಹೆಚ್ಚುವರಿ ಸ್ಥಳ ಪೂರೈಕೆದಾರರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ಹೆಚ್ಚಿನ ಸ್ಥಳ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಳ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
@@ -638,8 +638,8 @@
<string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ಪ್ರತಿ ಬಾರಿಯೂ ನಿಮ್ಮ ಬೆರಳಿನ ಸ್ಥಾನವನ್ನು ಸ್ವಲ್ಪ ಮಟ್ಟಿಗೆ ಬದಲಾಯಿಸಿ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string>
@@ -766,8 +766,8 @@
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳಿಗೆ ವಿರುದ್ಧವಾಗಿ ನೆಟ್‍‍ವರ್ಕ್ ಬಳಕೆಯನ್ನು ಹೇಗೆ ಲೆಕ್ಕಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳಲ್ಲಿ ಬಳಸಲಾಗುವುದಿಲ್ಲ."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessNotifications" msgid="761730149268789668">"ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೂಲಕ ಪೋಸ್ಟ್ ಮಾಡಿರುವ ಅಧಿಸೂಚನೆಗಳೂ ಸೇರಿದಂತೆ, ಅಂತಹ ಅಧಿಸೂಚನೆಗಳನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳಲು, ಪರೀಕ್ಷಿಸಲು ಮತ್ತು ತೆರವುಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"ಅಧಿಸೂಚನೆ ಕೇಳುಗರ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"ಅಧಿಸೂಚನೆ ಕೇಳುಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+ <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"ನೋಟಿಫಿಕೇಶನ್ ಕೇಳುಗರ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"ನೋಟಿಫಿಕೇಶನ್ ಕೇಳುಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"ಕಂಡೀಶನ್‌‌ ಪೂರೈಕೆದಾರರ ಸೇವೆಯನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"ಕಂಡೀಶನ್‌ ಪೂರೈಕೆದಾರರ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"ಕನಸಿನ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
@@ -1296,7 +1296,7 @@
<string name="ringtone_silent" msgid="397111123930141876">"ಯಾವುದೂ ಇಲ್ಲ"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"ರಿಂಗ್‌ಟೋನ್‌ಗಳು"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"ಅಲಾರಮ್ ಧ್ವನಿಗಳು"</string>
- <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"ಅಧಿಸೂಚನೆ ಧ್ವನಿಗಳು"</string>
+ <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"ನೋಟಿಫಿಕೇಶನ್ ಧ್ವನಿಗಳು"</string>
<string name="ringtone_unknown" msgid="5059495249862816475">"ಅಪರಿಚಿತ"</string>
<string name="wifi_available_sign_in" msgid="381054692557675237">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
<string name="network_available_sign_in" msgid="1520342291829283114">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
@@ -1492,10 +1492,10 @@
<string name="accessibility_binding_label" msgid="1974602776545801715">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="wallpaper_binding_label" msgid="1197440498000786738">"ವಾಲ್‌ಪೇಪರ್"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"ವಾಲ್‌ಪೇಪರ್ ಬದಲಿಸಿ"</string>
- <string name="notification_listener_binding_label" msgid="2702165274471499713">"ಅಧಿಸೂಚನೆ ಕೇಳುಗ"</string>
+ <string name="notification_listener_binding_label" msgid="2702165274471499713">"ನೋಟಿಫಿಕೇಶನ್‍ ಕೇಳುಗ"</string>
<string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ಕೇಳುವಿಕೆ"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"ಕಂಡೀಶನ್ ಪೂರೈಕೆದಾರರು"</string>
- <string name="notification_ranker_binding_label" msgid="432708245635563763">"ಅಧಿಸೂಚನೆ ಶ್ರೇಣಿಯ ಸೇವೆ"</string>
+ <string name="notification_ranker_binding_label" msgid="432708245635563763">"ನೋಟಿಫಿಕೇಶನ್ ರ‍್ಯಾಂಕರ್ ಸೇವೆ"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"<xliff:g id="APP">%s</xliff:g> ಮೂಲಕ VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
<string name="vpn_text" msgid="2275388920267251078">"ನೆಟ್‍ವರ್ಕ್ ನಿರ್ವಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -1695,10 +1695,10 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"ಆನ್ ಮಾಡಬೇಡಿ"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ಆನ್ ಆಗಿದೆ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ಆಫ್ ಆಗಿದೆ"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ನಿಮ್ಮ ಸಾಧನದ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಹೊಂದಲು <xliff:g id="SERVICE">%1$s</xliff:g>ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ನಿಮ್ಮ ಸಾಧನದ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಹೊಂದಲು <xliff:g id="SERVICE">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಅವಶ್ಯಕತೆಗಳ ಕುರಿತು ನಿಮಗೆ ಸಹಾಯ ಮಾಡುವ ಆ್ಯಪ್‌ಗಳಿಗೆ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣ ನೀಡುವುದು ಸೂಕ್ತವಾಗಿರುತ್ತದೆ, ಆದರೆ ಬಹುತೇಕ ಆ್ಯಪ್‌ಗಳಿಗೆ ಇದು ಸೂಕ್ತವಲ್ಲ."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ಸ್ಕ್ರೀನ್ ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ಇದು ಪರದೆಯ ಮೇಲಿನ ಎಲ್ಲಾ ವಿಷಯವನ್ನು ಓದಬಹುದು ಮತ್ತು ಇತರ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ವಿಷಯವನ್ನು ಪ್ರದರ್ಶಿಸಬಹುದು."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ಇದು ಪರದೆಯ ಮೇಲಿನ ಎಲ್ಲಾ ಕಂಟೆಂಟ್‌ ಅನ್ನು ಓದಬಹುದು ಮತ್ತು ಇತರ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ಕಂಟೆಂಟ್‌ ಅನ್ನು ಪ್ರದರ್ಶಿಸಬಹುದು."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ಕ್ರಿಯೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ಇದು ಆ್ಯಪ್ ಅಥವಾ ಹಾರ್ಡ್‌ವೇರ್ ಸೆನ್ಸರ್‌ನ ಜೊತೆಗಿನ ನಿಮ್ಮ ಸಂವಹನಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಬಹುದು, ಮತ್ತು ನಿಮ್ಮ ಪರವಾಗಿ ಆ್ಯಪ್‌ಗಳ ಜೊತೆ ಸಂವಹನ ನಡೆಸಬಹುದು."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ಅನುಮತಿಸಿ"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿ ಇದನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ಈ ಆ್ಯಪ್ ಅನ್ನು Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗಾಗಿ ರಚಿಸಲಾಗಿದೆ. ಇದು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇತ್ತೀಚಿನ ಭದ್ರತೆ ಮತ್ತು ಗೌಪ್ಯತಾ ರಕ್ಷಣೆಗಳನ್ನು ಒಳಗೊಂಡಿರುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ ಅಥವಾ ಆ್ಯಪ್ ಡೆವಲಪರ್ ಅವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ಈ ಆ್ಯಪ್ Android ನ ಇತ್ತೀಚಿನ ಆವೃತ್ತಿಯ ಜೊತೆಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ ಅಥವಾ ಆ್ಯಪ್ ಡೆವಲಪರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ನೀವು ಹೊಸ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವಿರಿ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ವೀಕ್ಷಿಸಲು SMS ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ಕೆಲವು ಕಾರ್ಯನಿರ್ವಹಣೆ ಸೀಮಿತವಾಗಿರಬಹುದು"</string>
@@ -2092,7 +2093,7 @@
<string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ಆಫ್ ಮಾಡಿ"</string>
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ವರ್ಧಿತ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು Android 12 ರಲ್ಲಿ Android ಅಡಾಪ್ಟಿವ್ ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿವೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಸೂಚಿಸಿದ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಪ್ರತ್ಯುತ್ತರಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಯೋಜಿಸುತ್ತದೆ.\n\nವರ್ಧಿತ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಸಂಪರ್ಕ ಹೆಸರುಗಳು ಮತ್ತು ಸಂದೇಶಗಳಂತಹ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆ ವಿಷಯವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಈ ವೈಶಿಷ್ಟ್ಯವು ಫೋನ್ ಕರೆಗಳಿಗೆ ಉತ್ತರಿಸುವುದು ಮತ್ತು \'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ಅನ್ನು ನಿಯಂತ್ರಿಸುವಂತಹ ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ವಜಾಗೊಳಿಸಬಹುದು ಅಥವಾ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು."</string>
- <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ"</string>
+ <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ನೋಟಿಫಿಕೇಶನ್"</string>
<string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ವಿಸ್ತರಿಸಲು ಬ್ಯಾಟರಿ ಬಳಕೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ಬ್ಯಾಟರಿ ಸೇವರ್"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ಉದ್ಯೋಗದ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ವೈಯಕ್ತಿಕ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ವೈಯಕ್ತಿಕ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ನಿಂದ ಕರೆ ಮಾಡಬೇಕೇ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಬೇಕೇ?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ವೈಯಕ್ತಿಕ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ಉದ್ಯೋಗ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"ಕರೆ ಮಾಡಿ"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"ಬದಲಿಸಿ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ನೆಟ್‌ವರ್ಕ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ನೆಟ್‌ವರ್ಕ್ ಸಬ್‌ಸೆಟ್‌ನ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM ಕಾರ್ಪೊರೇಟ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a4d4a7338060..ec4c6827769b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g>에서는 액세스할 수 없습니다. 대신 휴대전화에서 시도해 보세요."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"이 앱은 Android 이전 버전에 맞게 설계되었습니다. 정상 동작하지 않을 수 있으며 최신 보안 및 개인 정보 보호 기능을 포함하지 않습니다. 업데이트를 확인하거나 앱 개발자에게 문의하세요."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"업데이트 확인"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"이 앱은 Android 최신 버전과 호환되지 않습니다. 업데이트를 확인하거나 앱 개발자에게 문의하세요."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"새 메시지 있음"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"SMS 앱을 열고 확인"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"일부 기능이 제한될 수 있음"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f599c2cea0f7..5cd22384f59c 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -41,7 +41,7 @@
<string name="badPin" msgid="888372071306274355">"Терилген эски PIN код туура эмес."</string>
<string name="badPuk" msgid="4232069163733147376">"Терилген PUK код туура эмес."</string>
<string name="mismatchPin" msgid="2929611853228707473">"Терилген PIN\'дер дал келбейт."</string>
- <string name="invalidPin" msgid="7542498253319440408">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+ <string name="invalidPin" msgid="7542498253319440408">"Узундугу 4төн 8ге чейинки сандан турган PIN кодду териңиз."</string>
<string name="invalidPuk" msgid="8831151490931907083">"Узундугу 8 же көбүрөөк сандан турган PUK-кодду териңиз."</string>
<string name="needPuk" msgid="3503414069503752211">"SIM картаңыз PUK менен кулпуланган. Кулпусун ачуу үчүн PUK кодун териңиз."</string>
<string name="needPuk2" msgid="3910763547447344963">"SIM картаны бөгөттөн чыгаруу үчүн PUK2 кодун териңиз."</string>
@@ -957,7 +957,7 @@
<string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Сырсөздү терүү үчүн таптаңыз"</font></string>
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Кулпуну ачуу үчүн сырсөздү териңиз"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Кулпуну ачуу үчүн PIN кодду териңиз"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN-код туура эмес."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN код туура эмес."</string>
<string name="keyguard_label_text" msgid="3841953694564168384">"Кулпусун ачуу үчүн Менюну андан соң 0 баскычын басыңыз."</string>
<string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Өзгөчө кырдаалдар кызматы"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"Интернет жок"</string>
@@ -995,7 +995,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"SIM картанын кулпусу ачылууда…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
@@ -1043,7 +1043,7 @@
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Үлгү менен ачуу."</string>
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Жүзүнөн таанып ачуу."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Пин код менен ачуу."</string>
- <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM-картанын кулпусун PIN-код менен ачуу."</string>
+ <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM-картанын кулпусун PIN код менен ачуу."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM-картанын кулпусун PUK-код менен ачуу."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Сырсөз менен ачуу."</string>
<string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Үлгү аймагы."</string>
@@ -1409,7 +1409,7 @@
<string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Медиа сактагычты талдоо"</string>
<string name="ext_media_new_notification_title" msgid="3517407571407687677">"Жаңы <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> иштебей жатат"</string>
- <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Жөндөө үчүн таптаңыз"</string>
+ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Орнотуу үчүн басыңыз"</string>
<string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Жөндөө үчүн тандаңыз"</string>
<string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Түзмөктү форматташыңыз керек болушу мүмкүн. Чыгаруу үчүн таптап коюңуз."</string>
<string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Сүрөттөрдү, видеолорду, ырларды жана башкаларды сактоо үчүн керек"</string>
@@ -1645,17 +1645,17 @@
<string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Үлгү унутулду"</string>
<string name="kg_wrong_pattern" msgid="1342812634464179931">"Графикалык ачкыч туура эмес"</string>
<string name="kg_wrong_password" msgid="2384677900494439426">"Сырсөз туура эмес"</string>
- <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN-код туура эмес"</string>
+ <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN код туура эмес"</string>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Бөгөттөн чыгаруу сүрөтүн тартыңыз"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"SIM-картанын PIN\'ин киргизиңиз"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"PIN\'ди киргизиңиз"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Сырсөз киргизиңиз"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM-карта азыр жарактан чыкты. Улантыш үчүн, PUK-кодду киргизиңиз. Көбүрөөк маалымат үчүн операторуңузга кайрылыңыз."</string>
- <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Сиз каалаган PIN-кодду териңиз"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Сиз каалаган PIN-кодду ырастаңыз"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Сиз каалаган PIN кодду териңиз"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Сиз каалаган PIN кодду ырастаңыз"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="5743634657721110967">"SIM картанын кулпусу ачылууда…"</string>
- <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN-код туура эмес."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+ <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN код туура эмес."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Узундугу 4төн 8ге чейинки сандан турган PIN кодду териңиз."</string>
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK-код 8 сандан турушу керек."</string>
<string name="kg_invalid_puk" msgid="4809502818518963344">"Туура PUK-кодду кайрадан териңиз. Кайталанган аракеттер SIM картаны биротоло жараксыз кылат."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN-коддор туура келбеди"</string>
@@ -1667,7 +1667,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Колдонуучу атыңыз же сырсөзүңүз туура эмес."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Колдонуучу атыңызды же сырсөзүңүздү унутуп калдыңызбы?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Эсеп текшерилүүдө…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Сиз PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Сиз PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Сиз сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Сиз бөгөттөн чыгаруу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Сиз планшетиңизди <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, планшет баштапкы абалына кайтарылат жана бардык берилиштериңиз өчүрүлөт."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Бул колдонмо эски Android версиясы үчүн түзүлгөн. Ал туура иштебеши мүмкүн жана анда коопсуздукту жана купуялыкты коргоонун эң акыркы мүмкүнчүлүктөрү камтылган эмес. Жаңыртууну издеп көрүңүз же колдонмону иштеп чыгуучуга кайрылыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңыртууларды текшерүү"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Бул колдонмо Android\'дин соңку версиясына шайкеш келбейт. Жаңыртууну издеп көрүңүз же колдонмону иштеп чыгуучуга кайрылыңыз."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сизге жаңы билдирүүлөр келди"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Көрүү үчүн SMS колдонмосун ачыңыз"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Айрым функциялар иштебеши мүмкүн"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 767720661335..a686349c1d13 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານ. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ແອັບນີ້ສ້າງຂຶ້ນສຳລັບ Android ເວີຊັນເກົ່າ. ມັນອາດເຮັດວຽກບໍ່ຖືກຕ້ອງ ແລະ ຮວມທັງບໍ່ມີຄວາມປອດໄພ ແລະ ການປ້ອງກັນຄວາມເປັນສ່ວນຕົວຫຼ້າສຸດ. ກວດສອບເພື່ອອັບເດດ ຫຼື ຕິດຕໍ່ນັກພັດທະນາແອັບ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ກວດເບິ່ງອັບເດດ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ແອັບນີ້ບໍ່ສາມາດໃຊ້ໄດ້ກັບ Android ເວີຊັນຫຼ້າສຸດ. ກວດສອບເພື່ອອັບເດດ ຫຼື ຕິດຕໍ່ນັກພັດທະນາແອັບ."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ທ່ານມີຂໍ້ຄວາມໃໝ່"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ເປີດແອັບ SMS ເພື່ອເບິ່ງ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ຄຸນສົມບັດບາງຢ່າງອາດຖືກຈຳກັດໄວ້"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index eb1ab564c283..4ae49ac1207d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nepavyksta pasiekti nuotolinio įrenginio iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ši programa sukurta senesnės versijos „Android“. Ji gali tinkamai neveikti ir joje nėra naujausių saugos ir privatumo apsaugos priemonių. Patikrinkite, ar yra naujinių, arba susisiekite su programos kūrėju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tikrinti, ar yra naujinių"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ši programa nesuderinama su naujausios versijos „Android“. Patikrinkite, ar yra naujinių, arba susisiekite su programos kūrėju."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Turite naujų pranešimų"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Atidaryti SMS programą, norint peržiūrėti"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Kai kurios funkcijos ribojamos"</string>
@@ -2337,7 +2338,7 @@
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%s</xliff:g>. Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
- <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Sukonfigūruotos fizinės klaviatūros"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Palieskite, kad peržiūrėtumėte klaviatūras"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1bfda1b4aece..38530f1d82f1 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1698,7 +1698,7 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZSLĒGTA"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vai atļaut pakalpojumam <xliff:g id="SERVICE">%1$s</xliff:g> pilnībā kontrolēt jūsu ierīci?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Pilnīga kontrole ir piemērota lietotnēm, kas nepieciešamas lietotājiem ar īpašām vajadzībām, taču ne lielākajai daļai lietotņu."</string>
- <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Skatīt un pārvaldīt ekrānu"</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekrāna skatīšana un pārvaldīšana"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Tā var nolasīt visu ekrānā esošo saturu un attēlot saturu citām lietotnēm."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Darbību skatīšana un veikšana"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Tā var izsekot jūsu mijiedarbību ar lietotni vai aparatūras sensoru un mijiedarboties ar lietotnēm jūsu vārdā."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ierīcē <xliff:g id="DEVICE">%1$s</xliff:g> nevar piekļūt šai funkcijai. Mēģiniet tai piekļūt tālrunī."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Šī lietotne ir paredzēta vecākai Android versijai. Tā var nedarboties pareizi un neietver jaunākās drošības un konfidencialitātes aizsardzības funkcijas. Pārbaudiet atjauninājumu pieejamību vai sazinieties ar lietotnes izstrādātāju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Meklēt atjauninājumu"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jums ir jaunas īsziņas."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Lai skatītu, atveriet īsziņu lietotni."</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funkcijas var būt ierobežotas"</string>
@@ -2166,20 +2168,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Vai atvērt lietotni <xliff:g id="APP">%s</xliff:g> darba profilā?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vai atvērt lietotnes <xliff:g id="APP">%s</xliff:g> personīgajā profilā?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Vai atvērt lietotnes <xliff:g id="APP">%s</xliff:g> darba profilā?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vai zvanīt no darba lietotnes?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vai pārslēgties uz darba lietotni?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Jūsu organizācija ļauj jums veikt zvanus tikai no darba lietotnēm."</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Jūsu organizācija ļauj jums sūtīt ziņojumus tikai no darba lietotnēm."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Izmantot personīgo pārlūku"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Izmantot darba pārlūku"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Zvanīt"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Pārslēgties"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM tīkla atbloķēšanas PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM tīkla apakškopas atbloķēšanas PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM Corporate atbloķēšanas PIN"</string>
diff --git a/core/res/res/values-mcc310-mnc030-eu/strings.xml b/core/res/res/values-mcc310-mnc030-eu/strings.xml
index 45ce09126146..3bd918d70b96 100644
--- a/core/res/res/values-mcc310-mnc030-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc030-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="656054059094417927">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="1782569305985001089">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="1782569305985001089">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="8246632898824321280">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
index 76e30b01c29d..e9f761fb6aac 100644
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="3527626511418944853">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="3527626511418944853">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="3948912590657398489">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
index fbf70441fe4c..13989514e49e 100644
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="499832197298480670">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="499832197298480670">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="2346111479504469688">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc380-eu/strings.xml b/core/res/res/values-mcc310-mnc380-eu/strings.xml
index c3fb1bc649d4..8d7e3553b385 100644
--- a/core/res/res/values-mcc310-mnc380-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-eu/strings.xml
@@ -21,5 +21,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="6084322234976891423">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="6084322234976891423">"Ez da onartzen SIMa MM#3"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
index b023bccae8b4..dc3a4081a95e 100644
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="2604694337529846283">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="2604694337529846283">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="3099618295079374317">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc560-eu/strings.xml b/core/res/res/values-mcc310-mnc560-eu/strings.xml
index a0a46f666782..8b2e7d41a587 100644
--- a/core/res/res/values-mcc310-mnc560-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc560-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="3526528316378889524">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="4618730283812066268">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="4618730283812066268">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="8522039751358990401">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
index 5a34371f80c7..92de2626a3af 100644
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="7801541624846497489">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="7801541624846497489">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="7066936962628406316">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
index d843c4fa4f19..3cacf6bfe086 100644
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-eu/strings.xml
@@ -21,6 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"Ez dago SIMik MM#2"</string>
- <string name="mmcc_illegal_ms" msgid="4073997279280371621">"Ez da onartzen SIM txartela MM#3"</string>
+ <string name="mmcc_illegal_ms" msgid="4073997279280371621">"Ez da onartzen SIMa MM#3"</string>
<string name="mmcc_illegal_me" msgid="4936539345546223576">"Telefonoa ez da onartzen MM#6"</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6c570c230c56..7fa2fc510886 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -91,7 +91,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус на мобилна мрежа"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS-пораки"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Пораки од говорна пошта"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Повикување преку Wi-Fi"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Повици преку Wi-Fi"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"Статус на SIM-картичка"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Статус на SIM-известувања со висок приоритет"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Рамноправен уред го побара режимот на TTY „FULL“"</string>
@@ -122,7 +122,7 @@
<string name="roamingTextSearching" msgid="5323235489657753486">"Пребарување за услуга"</string>
<string name="wfcRegErrorTitle" msgid="3193072971584858020">"Не може да се постави функцијата „Повици преку Wi-Fi“"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повици преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Проблем при регистрирањето на функцијата „Повици преку Wi‑Fi“ со операторот: <xliff:g id="CODE">%1$s</xliff:g>"</item>
@@ -130,15 +130,15 @@
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
<string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"Повикување преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"Повик преку WLAN"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"Повик преку WLAN на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Повици преку Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"Глас преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Повикување преку Wi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Повици преку Wi-Fi"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Повикување преку Wi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Повици преку Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Глас преку Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Повик преку WiFi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Исклучено"</string>
@@ -1723,7 +1723,7 @@
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За префрлање помеѓу функциите, допрете и задржете го копчето за пристапност."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За префрлање помеѓу функциите, повлечете нагоре со два прста и задржете."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За да се префрлите на друга функција, повлечете нагоре со два прста и задржете."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За префрлање помеѓу функциите, повлечете нагоре со три прста и задржете."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string>
<string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ова не може да се отвори на <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на вашиот телефон како алтернатива."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Оваа апликација е создадена за постара верзија на Android. Можеби нема да работи правилно и не ги вклучува најновите мерки за заштита на безбедноста и приватноста. Проверете дали има ажурирање или контактирајте со програмерот на апликацијата."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за ажурирање"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови пораки"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Отворете ја апликацијата за SMS за приказ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Некои функции се ограничени"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index cea69ea5bcaf..5fa3b52d7000 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> ഉപകരണത്തിൽ ഇത് ആക്‌സസ് ചെയ്യാനാകില്ല. പകരം നിങ്ങളുടെ ഫോണിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായാണ് സൃഷ്ടിച്ചിരിക്കുന്നത്. ഇത് ശരിയായി പ്രവർത്തിക്കണമെന്നില്ല, ഏറ്റവും പുതിയ സുരക്ഷാ, സ്വകാര്യതാ പരിരക്ഷകൾ ഇതിൽ ഉൾപ്പെടുന്നുമില്ല. അപ്ഡേറ്റിനായി തിരയുക അല്ലെങ്കിൽ ആപ്പിന്റെ ഡെവലപ്പറെ ബന്ധപ്പെടുക."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ഈ ആപ്പ്, Android-ന്റെ എറ്റവും പുതിയ പതിപ്പിന് അനുയോജ്യമല്ല. അപ്ഡേറ്റിന് തിരയുക അല്ലെങ്കിൽ ആപ്പിന്റെ ഡെവലപ്പറെ ബന്ധപ്പെടുക."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"നിങ്ങൾക്ക് പുതിയ സന്ദേശങ്ങൾ ഉണ്ട്"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"കാണുന്നതിന് SMS ആപ്പ് തുറക്കുക"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ചില പ്രവർത്തനം പരിമിതപ്പെടാം"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ഔദ്യോഗിക <xliff:g id="APP">%s</xliff:g> തുറക്കണോ?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"സ്വകാര്യ <xliff:g id="APP">%s</xliff:g> എന്നതിൽ തുറക്കണോ?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ഔദ്യോഗിക <xliff:g id="APP">%s</xliff:g> എന്നതിൽ തുറക്കണോ?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"ഔദ്യോഗിക ആപ്പിൽ നിന്ന് കോൾ ചെയ്യണോ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ഔദ്യോഗിക ആപ്പിലേക്ക് മാറണോ?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് കോളുകൾ ചെയ്യാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് സന്ദേശമയയ്ക്കാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"വ്യക്തിപരമായ ബ്രൗസർ ഉപയോഗിക്കുക"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ഔദ്യോഗിക ബ്രൗസർ ഉപയോഗിക്കുക"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"കോൾ ചെയ്യുക"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"മാറുക"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"സിം നെറ്റ്‌വർക്ക് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"സിം നെറ്റ്‌വർക്ക് സബ്സെറ്റ് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"സിം കോർപ്പറേറ്റ് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index cfbb28e50645..204cf39de5f6 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g>-с хандах боломжгүй. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Энэ аппыг Android-н хуучин хувилбарт зориулж бүтээсэн. Энэ нь зохих ёсоор ажиллахгүй байж магадгүй бөгөөд хамгийн сүүлийн үеийн аюулгүй байдал болон нууцлалын хамгаалалтыг агуулдаггүй. Шинэчлэлт байгаа эсэхийг шалгах эсвэл аппын хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Энэ апп Android-н хамгийн сүүлийн үеийн хувилбартай тохиромжгүй. Шинэчлэлт байгаа эсэхийг шалгах эсвэл аппын хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ мессежүүд байна"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Үзэхийн тулд SMS аппыг нээх"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Зарим функцийг хязгаарласан байж болзошгүй"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Ажлын <xliff:g id="APP">%s</xliff:g>-г нээх үү?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Хувийн <xliff:g id="APP">%s</xliff:g>-д нээх үү?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Ажлын <xliff:g id="APP">%s</xliff:g>-д нээх үү?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ажлын аппаас залгах уу?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Ажлын апп руу сэлгэх үү?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Танай байгууллага танд зөвхөн ажлын аппуудаас дуудлага хийхийг зөвшөөрдөг"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Танай байгууллага танд зөвхөн ажлын аппуудаас мессеж илгээхийг зөвшөөрдөг"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Хувийн хөтөч ашиглах"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Ажлын хөтөч ашиглах"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Залгах"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Сэлгэх"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Сүлжээний SIM-н түгжээг тайлах ПИН"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Сүлжээний дэд олонлогийн SIM-н түгжээг тайлах ПИН"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Байгууллагын SIM-н түгжээг тайлах ПИН"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0cf09f189453..c728050bfa2b 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1082,7 +1082,7 @@
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"स्पेस"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"एंटर"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"हटवा"</string>
- <string name="search_go" msgid="2141477624421347086">"शोध"</string>
+ <string name="search_go" msgid="2141477624421347086">"शोधा"</string>
<string name="search_hint" msgid="455364685740251925">"शोधा…"</string>
<string name="searchview_description_search" msgid="1045552007537359343">"शोधा"</string>
<string name="searchview_description_query" msgid="7430242366971716338">"शोध क्वेरी"</string>
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"रंग सुधारणा"</string>
<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>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्रे"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"हे तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अ‍ॅक्सेस केले जाऊ शकत नाही. त्याऐवजी तुमच्या फोनवर अ‍ॅक्सेस करून पहा."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"हे ॲप Android च्या जुन्या आवृत्तीसाठी तयार केले होते. ते कदाचित व्यवस्थित काम करणार नाही आणि त्यामध्ये सुरक्षा व गोपनीयतेशी संबंधित नवीनतम संरक्षणे समाविष्ट नाहीत. अपडेटसाठी तपासा किंवा अ‍ॅपच्या डेव्हलपरशी संपर्क साधा."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेटसाठी तपासा"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"हे ॲप Android च्या नवीनतम आवृत्तीशी कंपॅटिबल नाही. अपडेटसाठी तपासा किंवा अ‍ॅपच्या डेव्हलपरशी संपर्क साधा."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपल्याकडे नवीन मेसेज आहेत"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"पाहण्‍यासाठी SMS अ‍ॅप उघडा"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"काही कार्यक्षमता मर्यादित असू शकतात"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ऑफिसची प्रोफाइल <xliff:g id="APP">%s</xliff:g> उघडायची आहे का?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"वैयक्तिक प्रोफाइल <xliff:g id="APP">%s</xliff:g> मध्ये उघडायची आहे का?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ऑफिसची प्रोफाइल <xliff:g id="APP">%s</xliff:g> मध्ये उघडायची आहे का?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"work app मधून कॉल करायचा आहे का?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"work app वर स्विच करायचे आहे का?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"तुमची संस्था तुम्हाला फक्त work app वरून कॉल करण्याची अनुमती देते"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"तुमची संस्था तुम्हाला फक्त work app वरून मेसेज पाठवण्याची अनुमती देते"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"वैयक्तिक ब्राउझर वापरा"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउझर वापरा"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"कॉल करा"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"स्विच करा"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क अनलॉक पिन"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM नेटवर्क सबसेट अनलॉक पिन"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM कॉर्पोरेट अनलॉक पिन"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index e8c5ab9a1058..5cb9c09890fe 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"HIDUP"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"MATI"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Benarkan <xliff:g id="SERVICE">%1$s</xliff:g> mempunyai kawalan penuh atas peranti anda?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda berkaitan dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengawal skrin"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ciri ini boleh membaca semua kandungan pada skrin dan memaparkan kandungan di atas apl lain."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Lihat dan laksanakan tindakan"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Apl ini tidak boleh diakses pada <xliff:g id="DEVICE">%1$s</xliff:g> anda. Cuba pada telefon anda."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Apl ini dibina untuk versi Android yang lebih lama. Apl ini mungkin tidak berfungsi dengan betul dan tidak termasuk perlindungan keselamatan dan privasi yang terkini. Semak kemas kini atau hubungi pembangun apl."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Semak kemaskinian"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Apl ini tidak serasi dengan versi terbaharu Android. Semak kemaskinian atau hubungi pembangun apl."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Anda mempunyai mesej baharu"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buka apl SMS untuk melihat"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sesetengah fungsi mungkin terhad"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index c643e863ad47..d90c5b825537 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -635,7 +635,7 @@
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
<string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ဖွင့်ပိတ်ခလုတ် နှိပ်လိုက်သည်"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း လက်ချောင်းအနေအထားကို အနည်းငယ်ပြောင်းပါ"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"လက်ချောင်းအနေအထား နည်းနည်းစီ ပြောင်းပါ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"လက်ဗွေကို မသိရှိပါ"</string>
@@ -681,8 +681,8 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"အလင်းရောင် အားနည်းသည်"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"ဖုန်းကို အဝေးသို့ခွာပါ"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"ဖုန်းကို အနားသို့ပိုတိုးပါ"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"ဖုန်းကို ပိုမြှင့်လိုက်ပါ"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"ဖုန်းကို ပိုနှိမ့်လိုက်ပါ"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"ဖုန်းကို မြှင့်လိုက်ပါ"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"ဖုန်းကို နှိမ့်လိုက်ပါ"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"ဖုန်းကို သင့်ဘယ်ဘက်သို့ ရွှေ့ပါ"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"ဖုန်းကို သင့်ညာဘက်သို့ ရွှေ့ပါ"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"သင့်စက်ပစ္စည်းကို တည့်တည့်ကြည့်ပါ။"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"၎င်းကို သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> တွင် သုံး၍မရပါ။ ဖုန်းတွင် စမ်းကြည့်ပါ။"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ဤအက်ပ်ကို ဗားရှင်းဟောင်းအတွက် ရေးထားသည်။ ၎င်းကမှန်ကန်စွာ လုပ်ဆောင်နိုင်မည်မဟုတ်ဘဲ နောက်ဆုံးထုတ် လုံခြုံရေးနှင့် ကိုယ်ရေးအချက်အလက်လုံခြုံမှု အကာအကွယ်များ မပါဝင်ပါ။ အပ်ဒိတ်ရှာကြည့်ပါ (သို့) အက်ပ်ရေးသူထံ ဆက်သွယ်ပါ။"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"အပ်ဒိတ်စစ်ရန်"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ဤအက်ပ်သည် Android နောက်ဆုံးဗားရှင်းနှင့် တွဲမသုံးနိုင်ပါ။ အပ်ဒိတ်ရှာကြည့်ပါ (သို့) အက်ပ်ရေးသူထံ ဆက်သွယ်ပါ။"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"သင့်ထံတွင် စာအသစ်များရောက်နေသည်"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ကြည့်ရှုရန် SMS အက်ပ်ကိုဖွင့်ပါ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"လုပ်ဆောင်ချက် ကန့်သတ်မှုရှိနိုင်သည်"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"အလုပ်သုံး <xliff:g id="APP">%s</xliff:g> ဖွင့်မလား။"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ကိုယ်ပိုင် <xliff:g id="APP">%s</xliff:g> တွင် ဖွင့်မလား။"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"အလုပ် <xliff:g id="APP">%s</xliff:g> တွင် ဖွင့်မလား။"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"အလုပ်သုံးအက်ပ်မှ ဖုန်းဆက်မလား။"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"အလုပ်သုံးအက်ပ်သို့ ပြောင်းမလား။"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ ဖုန်းဆက်ခွင့်ပြုသည်"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ မက်ဆေ့ဂျ်ပို့ခွင့်ပြုသည်"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ကိုယ်ပိုင်ဘရောင်ဇာ သုံးရန်"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"အလုပ်သုံးဘရောင်ဇာ သုံးရန်"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"ဖုန်းဆက်ရန်"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"ပြောင်းရန်"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ဆင်းမ်ကွန်ရက် လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ဆင်းမ်ကွန်ရက်ခွဲ လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ဆင်းမ်ကော်ပိုရိတ် လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index adb1b522ec0b..845eb92dc559 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g>. Prøv på telefonen din i stedet."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Denne appen er utviklet for en eldre Android-versjon. Det er ikke sikkert at den fungerer som den skal, og den mangler det nyeste innen sikkerhet og personvern. Se etter en oppdatering, eller kontakt utvikleren av appen."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Se etter oppdateringer"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Denne appen er ikke kompatibel med den nyeste versjonen av Android. Se etter en oppdatering, eller kontakt utvikleren av appen."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye meldinger"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Åpne SMS-appen for å se"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Enkelte funksjoner kan begrenses"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Vil du åpne <xliff:g id="APP">%s</xliff:g> for jobb?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vil du åpne i <xliff:g id="APP">%s</xliff:g> for personlig bruk?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Vil du åpne i <xliff:g id="APP">%s</xliff:g> for jobb?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vil du ringe fra en jobbapp?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vil du bytte til en jobbapp?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisasjonen din tillater bare at du ringer fra jobbapper"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisasjonen din tillater bare at du sender meldinger fra jobbapper"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Bruk den personlige nettleseren"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Bruk jobbnettleseren"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Ring"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Bytt"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-kode for å fjerne operatørlåser"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-kode for å fjerne bestemte operatørlåser"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-kode for å låse opp SIM-kort for bedrifter"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b71d30c7f1d4..47bdcf07ea1e 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -179,7 +179,7 @@
<string name="low_memory" product="watch" msgid="3479447988234030194">"भण्डारण भरिएको छ हेर्नुहोस्। ठाउँ खाली गर्न केही फाइलहरू मेटाउनुहोस्।"</string>
<string name="low_memory" product="tv" msgid="6663680413790323318">"Android टिभी डिभाइसको भण्डारण भरिएको छ। ठाउँ खाली गर्न केही फाइलहरू मेट्नुहोस्।"</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"फोन भण्डारण भरिएको छ! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
- <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{प्रमाणपत्र जारी गर्ने निकाय इन्स्टल गरियो}other{प्रमाणपत्र जारी गर्ने निकायहरू इन्स्टल गरियो}}"</string>
+ <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{प्रमाणपत्र जारी गर्ने निकायको प्रमाणपत्र इन्स्टल गरियो}other{प्रमाणपत्र जारी गर्ने निकायका प्रमाणपत्रहरू इन्स्टल गरिए}}"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"अज्ञात तेस्रो पक्ष द्वारा"</string>
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"तपाईंको कार्य प्रोफाइलका प्रशासकद्वारा"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> द्वारा"</string>
@@ -206,7 +206,7 @@
<string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
<string name="personal_apps_suspension_title" msgid="7561416677884286600">"आफ्नो कार्य प्रोफाइल अन गर्नुहोस्"</string>
<string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत एपहरूलाई रोक लगाइन्छ"</string>
- <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एडमिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
+ <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एड्मिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"अन गर्नुहोस्"</string>
<string name="work_profile_telephony_paused_title" msgid="7690804479291839519">"कल वा म्यासेज अफ गरिएको छ"</string>
<string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"तपाईंले कामसम्बन्धी एपहरू पज गर्नुभएको छ। तपाईं फोन कल वा टेक्स्ट म्यासेजहरू प्राप्त गर्नु हुने छैन।"</string>
@@ -995,7 +995,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"SIM कार्ड अनलक गरिँदै छ…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत PIN टाइप गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो Google खाता मार्फत साइन इन गरेर आफ्नो Android टिभी डिभाइस अनलक गर्न अनुरोध गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"तपाईँले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
@@ -1633,7 +1633,7 @@
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"सेटिंङहरू"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"डिस्कनेक्ट गर्नुहोस्"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"स्क्यान गर्दै ..."</string>
- <string name="media_route_status_connecting" msgid="5845597961412010540">"जडान हुँदै..."</string>
+ <string name="media_route_status_connecting" msgid="5845597961412010540">"कनेक्ट गरिँदै छ..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"उपलब्ध"</string>
<string name="media_route_status_not_available" msgid="480912417977515261">"उपलब्ध छैन"</string>
<string name="media_route_status_in_use" msgid="6684112905244944724">"प्रयोगमा छ"</string>
@@ -1667,7 +1667,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"के तपाईँले उपयोगकर्ता नाम वा पासवर्ड बिर्सनुभयो?\n"<b>"google.com/accounts/recovery"</b>" मा जानुहोस्।"</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"खाता जाँच हुँदै…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत PIN टाइप गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट डिफल्ट कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"सक्रिय"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्न दिनु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप चलाउन मिल्दैन। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"यो एप Android को पुरानो संस्करणका लागि निर्माण गरिएको थियो। यो एपले राम्ररी काम नगर्न सक्छ र यसमा सुरक्षा तथा गोपनीयतासम्बन्धी पछिल्ला सुरक्षा सुविधाहरू समावेश नहुन सक्छन्। यस एपको नवीनतम संस्करण उपलब्ध छ कि छैन हेर्नुहोस् वा एपका विकासकर्तासँग सम्पर्क गर्नुहोस्।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेट उपलब्ध छ वा छैन जाँच्नुहोस्"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"यो एप Android को नवीनतम संस्करणसँग कम्प्याटिबल छैन। यस एपको नवीनतम संस्करण उपलब्ध छ कि छैन भन्ने कुरा हेर्नुहोस् वा एपका विकासकर्तालाई सम्पर्क गर्नुहोस्।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"तपाईंलाई नयाँ सन्देश आएको छ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"हेर्नका लागि SMS एप खोल्नुहोस्"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"केही सुविधा राम्ररी नचल्न सक्छन्"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"कामसम्बन्धी <xliff:g id="APP">%s</xliff:g> खोल्ने हो?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"व्यक्तिगत <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"कामसम्बन्धी <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"कामसम्बन्धी एपबाट कल गर्ने हो?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"कामसम्बन्धी एप प्रयोग गर्ने हो?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र कल गर्ने अनुमति दिन्छ"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र म्यासेज पठाउने अनुमति दिन्छ"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"व्यक्तिगत ब्राउजर प्रयोग गर्नुहोस्"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउजर प्रयोग गर्नुहोस्"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"कल गर्नुहोस्"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"बदल्नुहोस्"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM को नेटवर्क अनलक गर्ने PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM को नेटवर्कको सबसेट अनलक गर्ने PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM को कर्पोरेट लक खोल्ने PIN"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 345807b7300d..f2b03086ea94 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Je hebt hier geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je telefoon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Deze app is ontworpen voor een oudere versie van Android. De app werkt misschien niet goed en bevat niet de nieuwste beveiligings- en privacybeschermingsopties. Check op een update of neem contact op met de ontwikkelaar van de app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op updates"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Deze app is niet compatibel met de nieuwste versie van Android. Check of er updates zijn of neem contact op met de ontwikkelaar van de app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open je sms-app om ze te bekijken"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Functionaliteit kan beperkt zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index bf31408c5ebb..5d1de82e71f5 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1081,7 +1081,7 @@
<string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"ସ୍ପେସ୍‍"</string>
<string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର୍"</string>
- <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ କରନ୍ତୁ…"</string>
<string name="searchview_description_search" msgid="1045552007537359343">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
@@ -1147,7 +1147,7 @@
<string name="paste" msgid="461843306215520225">"ପେଷ୍ଟ କରନ୍ତୁ"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"ସାଦା ଟେକ୍ସଟ୍‍ ଭାବରେ ପେଷ୍ଟ କରନ୍ତୁ"</string>
<string name="replace" msgid="7842675434546657444">"ବଦଳାନ୍ତୁ…"</string>
- <string name="delete" msgid="1514113991712129054">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+ <string name="delete" msgid="1514113991712129054">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="copyUrl" msgid="6229645005987260230">"URL କପି କରନ୍ତୁ"</string>
<string name="selectTextMode" msgid="3225108910999318778">"ଟେକ୍ସଟ୍‍ ଚୟନ କରନ୍ତୁ"</string>
<string name="undo" msgid="3175318090002654673">"ପୂର୍ବ ପରି କରନ୍ତୁ"</string>
@@ -1155,7 +1155,7 @@
<string name="autofill" msgid="511224882647795296">"ଅଟୋଫିଲ୍‌"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"ଟେକ୍ସଟ୍‍ ଚୟନ"</string>
<string name="addToDictionary" msgid="8041821113480950096">"ଶବ୍ଦକୋଷରେ ଯୋଗ କରନ୍ତୁ"</string>
- <string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+ <string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="inputMethod" msgid="1784759500516314751">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"ଟେକ୍ସଟ୍‌ କାର୍ଯ୍ୟ"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ପଛକୁ ଫେରନ୍ତୁ"</string>
@@ -1369,7 +1369,7 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ଆନାଲଗ୍‍ ଅଡିଓ ଆକ୍ସେସରୀ ଚିହ୍ନଟ ହେଲା"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ଏହି ଫୋନ୍‌ରେ କନେକ୍ଟ ଥିବା ଡିଭାଇସ୍‍ କମ୍ପାଟିବଲ୍‍ ନୁହେଁ। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ କରାଯାଇଛି"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ ହୋଇଛି"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"USB ଡିବଗିଂକୁ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ସଂଯୋଗ କରାଯାଇଛି"</string>
@@ -1513,7 +1513,7 @@
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"ଡ୍ରାଇଭିଙ୍ଗ ଆପ୍‌ରୁ ବାହାରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="back_button_label" msgid="4078224038025043387">"ଫେରନ୍ତୁ"</string>
<string name="next_button_label" msgid="6040209156399907780">"ପରବର୍ତ୍ତୀ"</string>
- <string name="skip_button_label" msgid="3566599811326688389">"ଛାଡ଼ିଦିଅନ୍ତୁ"</string>
+ <string name="skip_button_label" msgid="3566599811326688389">"ବାଦ ଦିଅନ୍ତୁ"</string>
<string name="no_matches" msgid="6472699895759164599">"କୌଣସି ମେଳକ ନାହିଁ"</string>
<string name="find_on_page" msgid="5400537367077438198">"ପୃଷ୍ଠାରେ ଖୋଜନ୍ତୁ"</string>
<string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{#ଟି ମେଳ}other{{total}ଟିରୁ #ଟି ମେଳ}}"</string>
@@ -1557,7 +1557,7 @@
<string name="date_picker_next_month_button" msgid="4858207337779144840">"ପରବର୍ତ୍ତୀ ମାସ"</string>
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"ALT"</string>
<string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ କରନ୍ତୁ"</string>
- <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+ <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍‍ ପରିବର୍ତ୍ତନ"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"ଶିଫ୍ଟ"</string>
@@ -1663,7 +1663,7 @@
<string name="kg_login_instructions" msgid="3619844310339066827">"ଅନଲକ୍‌ କରିବା ପାଇଁ, ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟ ସହ ସାଇନ୍-ଇନ୍ କରନ୍ତୁ।"</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"ୟୁଜରନେମ୍‍ (ଇମେଲ୍)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"ପାସୱାର୍ଡ"</string>
- <string name="kg_login_submit_button" msgid="893611277617096870">"ସାଇନ୍-ଇନ୍"</string>
+ <string name="kg_login_submit_button" msgid="893611277617096870">"ସାଇନ ଇନ କରନ୍ତୁ"</string>
<string name="kg_login_invalid_input" msgid="8292367491901220210">"ଅମାନ୍ୟ ୟୁଜରନେମ୍‍ କିମ୍ୱା ପାସ୍‌ୱର୍ଡ।"</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"ଆପଣଙ୍କର ୟୁଜରନେମ୍‍ କିମ୍ୱା ପାସ୍‌ୱର୍ଡ ଭୁଲି ଯାଇଛନ୍ତି କି?\n"<b>"google.com/accounts/recovery"</b>" ଭିଜିଟ୍‍ କରନ୍ତୁ।"</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"ଆକାଉଣ୍ଟ ଯାଞ୍ଚ କରାଯାଉଛି…"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ଏହି ଆପକୁ Androidର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ପାଇଁ ତିଆରି କରାଯାଇଛି। ଏହା ସଠିକ୍ ଭାବେ କାମ କରିନପାରେ ଏବଂ ଏଥିରେ ନବୀନତମ ସୁରକ୍ଷା ଏବଂ ଗୋପନୀୟତା ସୁରକ୍ଷାଗୁଡ଼ିକ ଅନ୍ତର୍ଭୁକ୍ତ ନାହିଁ। ଏକ ଅପଡେଟ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଆପର ଡେଭେଲପରଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ଅପଡେଟ୍‌ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ଏହି ଆପ Androidର ନବୀନତମ ଭର୍ସନ ସହ କମ୍ପାଟିବଲ ନୁହେଁ। ଏକ ଅପଡେଟ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଆପର ଡେଭେଲପରଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ଆପଣଙ୍କ ପାଖରେ ନୂଆ ମେସେଜ୍‍ ରହିଛି"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ଦେଖିବା ପାଇଁ SMS ଆପ୍‍ ଖୋଲନ୍ତୁ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ହୁଏତ କିଛି ପ୍ରକାର୍ଯ୍ୟ ସୀମିତ ହୋଇପାରେ"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ୱାର୍କ <xliff:g id="APP">%s</xliff:g>କୁ ଖୋଲିବେ?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ବ୍ୟକ୍ତିଗତ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ୱାର୍କ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"ୱାର୍କ ଆପରୁ କଲ କରିବେ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ୱାର୍କ ଆପକୁ ସୁଇଚ କରିବେ?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ ମେସେଜ ପଠାଇବା ପାଇଁ ଅନୁମତି ଦିଏ"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ବ୍ୟକ୍ତିଗତ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ୱାର୍କ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"କଲ କରନ୍ତୁ"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"ସୁଇଚ କରନ୍ତୁ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ନେଟୱାର୍କ ଅନଲକ୍ PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ନେଟୱାର୍କର ସବସେଟ୍ ଅନଲକ୍ PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM କର୍ପୋରେଟ୍ ଅନଲକ୍ PIN"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index b653127fcb8f..25f7f7cf6976 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1633,7 +1633,7 @@
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"ਸੈਟਿੰਗਾਂ"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
- <string name="media_route_status_connecting" msgid="5845597961412010540">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
+ <string name="media_route_status_connecting" msgid="5845597961412010540">"ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"ਉਪਲਬਧ"</string>
<string name="media_route_status_not_available" msgid="480912417977515261">"ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="media_route_status_in_use" msgid="6684112905244944724">"ਵਰਤੋਂ ਵਿੱਚ"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਪੁਰਾਣੇ ਵਰਜਨ ਲਈ ਬਣਾਈ ਗਿਆ ਸੀ। ਸ਼ਾਇਦ ਇਹ ਠੀਕ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ ਅਤੇ ਨਵੀਨਤਮ ਸੁਰੱਖਿਆ ਅਤੇ ਪਰਦੇਦਾਰੀ ਸੰਬੰਧੀ ਸੁਰੱਖਿਆਵਾਂ ਸ਼ਾਮਲ ਨਾ ਹੋਣ। ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਐਪ ਦੇ ਵਿਕਾਸਕਾਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ਇਹ ਐਪ Android ਦੇ ਨਵੀਨਤਮ ਵਰਜਨ ਦੇ ਅਨੁਰੂਪ ਨਹੀਂ ਹੈ। ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਐਪ ਦੇ ਵਿਕਾਸਕਾਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ਦੇਖਣ ਲਈ SMS ਐਪ ਖੋਲ੍ਹੋ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ਕੁਝ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਸੀਮਤ ਹੋ ਸਕਦੀ ਹੈ"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ <xliff:g id="APP">%s</xliff:g> ਨੂੰ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ਕੀ ਨਿੱਜੀ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ ਐਪ ਤੋਂ ਕਾਲ ਕਰਨੀ ਹੈ?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਹੀ ਸੁਨੇਹੇ ਭੇਜਣ ਦਿੰਦੀ ਹੈ"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ਨਿੱਜੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ਕੰਮ ਸੰਬੰਧੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"ਕਾਲ ਕਰੋ"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"ਸਵਿੱਚ ਕਰੋ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ਸਿਮ ਨੈੱਟਵਰਕ ਅਣਲਾਕ ਪਿੰਨ"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ਸਿਮ ਨੈੱਟਵਰਕ ਸਬਸੈੱਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ਸਿਮ ਕਾਰਪੋਰੇਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 15f7d6ed1a9c..9871ccbccaa0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -688,7 +688,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"Przesuń telefon w lewo"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Przesuń telefon w prawo"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Patrz prosto na urządzenie."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Nie widać twarzy. Trzymaj telefon na wysokości oczu."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Nie widać twarzy – trzymaj telefon na wysokości oczu"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Telefon się porusza. Trzymaj go nieruchomo."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Zarejestruj swoją twarz ponownie."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Nie rozpoznaję twarzy. Spróbuj ponownie."</string>
@@ -704,7 +704,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Nie można utworzyć modelu twarzy. Spróbuj ponownie."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Wykryto ciemne okulary. Twarz musi być widoczna w całości."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Wykryto zasłonę twarzy. Twarz musi być widoczna w całości."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Wykryto zasłonę twarzy – twarz musi być widoczna w całości"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Nie można zweryfikować twarzy. Sprzęt niedostępny."</string>
@@ -967,7 +967,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Naciśnij Menu, aby odblokować lub wykonać połączenie alarmowe."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Naciśnij Menu, aby odblokować."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Narysuj wzór, aby odblokować"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Alarmowe"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Funkcje alarmowe"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Powrót do połączenia"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Poprawnie!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Spróbuj ponownie."</string>
@@ -1669,8 +1669,8 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Nie pamiętasz nazwy użytkownika lub hasła?\nWejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Sprawdzam konto"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Wpisałeś nieprawidłowy kod PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> został wpisany nieprawidłowy kod PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Narysowałeś nieprawidłowy wzór odblokowania <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Próbujesz odblokować urządzenie z Androidem TV w nieprawidłowy sposób. To była <xliff:g id="NUMBER_0">%1$d</xliff:g> próba. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach urządzenie zostanie zresetowane do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ta aplikacja jest na starszą wersję Androida. Może nie działać prawidłowo i nie uwzględnia najnowszych zabezpieczeń oraz ustawień ochrony prywatności. Sprawdź, czy możesz ją zaktualizować, lub skontaktuj się z deweloperem."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sprawdź dostępność aktualizacji"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ta aplikacja nie jest zgodna z najnowszą wersją Androida. Sprawdź, czy możesz ją zaktualizować, lub skontaktuj się z deweloperem."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Masz nowe wiadomości"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otwórz aplikację do SMS-ów, by wyświetlić wiadomość"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Część funkcji może być niedostępnych"</string>
@@ -2167,20 +2168,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Otworzyć aplikację służbową <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otworzyć w osobistej aplikacji <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Otworzyć w służbowej aplikacji <xliff:g id="APP">%s</xliff:g>?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Zadzwonić z aplikacji służbowej?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Przełączyć na aplikację służbową?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Twoja organizacja zezwala na nawiązywanie połączeń tylko z aplikacji służbowych"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Twoja organizacja zezwala na wysyłanie wiadomości tylko z aplikacji służbowych"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Użyj przeglądarki osobistej"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Użyj przeglądarki służbowej"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Zadzwoń"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Przełącz"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kod PIN do karty SIM odblokowujący sieć"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Kod PIN odblokowujący podzbiór sieci na karcie SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Kod PIN odblokowujący dane korporacyjne na karcie SIM"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index ced295833d94..2ce7094055ed 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível acessar essa configuração pelo seu <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Este app foi criado para uma versão mais antiga do Android. Ele pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Este app não é compatível com a versão mais recente do Android. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra o app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funções são limitadas"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ed5084f12835..ea30d7c3e322 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -313,7 +313,7 @@
<string name="permgroupdesc_storage" msgid="5378659041354582769">"aceder aos ficheiros no seu dispositivo"</string>
<string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
<string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"aceder a música e áudio no seu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"fotos e vídeos"</string>
<string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"aceder a fotos e vídeos no seu dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
@@ -687,7 +687,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"Mova o telemóvel para a sua esquerda"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Mova o telemóvel para a sua direita"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Olhe mais diretamente para o dispositivo."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Rosto não detetado. Segure o telemóvel ao nível dos olhos."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Rosto não detetado. Segure o telemóvel ao nível dos olhos"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Demasiado movimento. Mantenha o telemóvel firme."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Volte a inscrever o rosto."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Impossível reconhecer o rosto. Tente novamente."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta app foi criada para uma versão mais antiga do Android. Pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se existem atualizações ou contacte o programador da app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rever atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Esta app não é compatível com a versão mais recente do Android. Verifique se existem atualizações ou contacte o programador da app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra a app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funcionalidades limitadas"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index ced295833d94..2ce7094055ed 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível acessar essa configuração pelo seu <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Este app foi criado para uma versão mais antiga do Android. Ele pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Este app não é compatível com a versão mais recente do Android. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra o app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funções são limitadas"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d4bddd3dbef7..e103148cba3b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nu se poate accesa pe <xliff:g id="DEVICE">%1$s</xliff:g>. Încearcă pe telefon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplicația a fost creată pentru o versiune mai veche de Android. Poate să nu funcționeze corect și nu include cele mai recente măsuri de protecție a securității și a confidențialității. Caută o actualizare sau contactează dezvoltatorul aplicației."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Caută actualizări"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplicația nu este compatibilă cu cea mai recentă versiune de Android. Caută o actualizare sau contactează dezvoltatorul aplicației."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ai mesaje noi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Deschide aplicația pentru SMS-uri ca să vezi"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Unele funcții ar putea fi limitate"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fb1d5c6c4418..cbdd5cb6cc86 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"На устройстве <xliff:g id="DEVICE">%1$s</xliff:g> эта функция недоступна. Используйте телефон."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Это приложение было разработано для более ранней версии Android. Оно не соответствует последним требованиям к обеспечению конфиденциальности и безопасности данных и может работать некорректно. Проверьте наличие обновлений или свяжитесь с разработчиком приложения."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверить обновления"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Это приложение не совместимо с последней версией Android. Проверьте наличие обновлений или свяжитесь с разработчиком приложения."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Новые сообщения"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Чтобы просмотреть, откройте приложение для обмена SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Некоторые функции могут не работать"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f1636dbe0825..7358a9acb3a2 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"මෙයට ඔබේ <xliff:g id="DEVICE">%1$s</xliff:g> මත ප්‍රවේශ විය නොහැක. ඒ වෙනුවට ඔබේ දුරකථනයෙහි උත්සාහ කරන්න."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"මෙම යෙදුම Android හි පැරණි අනුවාදයක් සඳහා තනා ඇත. එය නිසි ලෙස ක්‍රියා නොකරන අතර නවතම ආරක්ෂාව සහ රහස්‍යතා ආරක්‍ෂාව ඇතුළත් නොවේ. යාවත්කාලීනයක් සඳහා පරීක්ෂා කරන්න, නැතහොත් යෙදුමේ සංවර්ධකයා සම්බන්ධ කර ගන්න."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"යාවත්කාලීන සඳහා පරික්ෂා කරන්න"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"මෙම යෙදුම Android හි නවතම අනුවාදය සමග නොගැළපෙයි. යාවත්කාලීනයක් සඳහා පරීක්ෂා කරන්න නැතහොත් යෙදුමේ සංවර්ධකයා සම්බන්ධ කර ගන්න."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ඔබට නව පණිවිඩ තිබේ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"බැලීමට විවෘත SMS යෙදුම විවෘත කරන්න"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ඇතැම් ක්‍රියාකාරිත්ව සීමිත විය හැක"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f9c2a9b3dcb4..6c0e637d0e8d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte prístup k tomuto obsahu. Skúste použiť telefón."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Táto aplikácia bola vytvorená pre staršiu verziu Androidu. Nemusí správne fungovať a obsahovať najnovšie prvky zabezpečenia a ochrany súkromia. Skontrolujte dostupnosť aktualizácie alebo kontaktujte jej vývojára."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Skontrolovať dostupnosť aktualizácie"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové správy."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorte aplikáciu pre SMS a zobrazte správu"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Niektoré funkcie môžu byť obmedzené"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c120d2fbf282..90fa4ae188aa 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1702,7 +1702,7 @@
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ogledovanje in upravljanje zaslona"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Bere lahko vso vsebino na zaslonu ter prikaže vsebino prek drugih aplikacij."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Ogledovanje in izvajanje dejanj"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali senzorjem strojne opreme ter komunicira z aplikacijami v vašem imenu."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali tipalom strojne opreme ter komunicira z aplikacijami v vašem imenu."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dovoli"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zavrni"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Če želite začeti uporabljati funkcijo, se je dotaknite:"</string>
@@ -1717,7 +1717,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"Popravljanje barv"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni pripomočki"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ta aplikacija je bila razvita za starejšo različico Androida. Morda ne bo delovala pravilno ter ne vključuje najnovejših varnostnih funkcij in funkcij za varovanje zasebnosti. Preverite, ali je na voljo posodobitev, ali pa se obrnite na razvijalca aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Preveri, ali je na voljo posodobitev"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ta aplikacija ni združljiva z najnovejšo različico Androida. Preverite, ali je na voljo posodobitev, ali pa se obrnite na razvijalca aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nova sporočila."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Za ogled odprite aplikacijo za SMS-je"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Nekatere funkcije bodo morda omejene"</string>
@@ -2152,7 +2153,7 @@
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Skupinski pogovor"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
<string name="resolver_personal_tab" msgid="2051260504014442073">"Osebno"</string>
- <string name="resolver_work_tab" msgid="2690019516263167035">"Služba"</string>
+ <string name="resolver_work_tab" msgid="2690019516263167035">"Delo"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Pogled osebnega profila"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Pogled delovnega profila"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokiral skrbnik za IT"</string>
@@ -2167,20 +2168,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"Želite odpreti delovno aplikacijo <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"Želite odpreti v osebni aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Želite odpreti v delovni aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"Želite poklicati iz delovne aplikacije?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Želite preklopiti na delovno aplikacijo?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Organizacija vam omogoča klicanje samo iz delovnih aplikacij."</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organizacija vam omogoča pošiljanje sporočil samo iz delovnih aplikacij."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Uporabi osebni brskalnik"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Uporabi delovni brskalnik"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"Pokliči"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"Preklopi"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Koda PIN za odklepanje omrežja kartice SIM"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Koda PIN za odklepanje podnabora omrežja kartice SIM"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Koda PIN za odklepanje kartice SIM za podjetje"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 6cbbd28e97dc..b0762d29b3cb 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1698,9 +1698,9 @@
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Do të lejosh që <xliff:g id="SERVICE">%1$s</xliff:g> të ketë kontroll të plotë të pajisjes sate?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrolli i plotë është i përshtatshëm për aplikacionet që të ndihmojnë me nevojat e qasshmërisë, por jo për shumicën e aplikacioneve."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Shiko dhe kontrollo ekranin"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ai mund të lexojë të gjithë përmbajtjen në ekran dhe të shfaqë përmbajtjen mbi aplikacione të tjera."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Mund të lexojë të gjithë përmbajtjen në ekran dhe të shfaqë përmbajtjen mbi aplikacione të tjera."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Shiko dhe kryej veprimet"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ai mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Lejo"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzo"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Trokit te një veçori për të filluar ta përdorësh atë:"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g>. Provoje në telefon më mirë."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ky aplikacion është krijuar për një version më të vjetër të Android. Mund të mos funksionojë siç duhet dhe nuk përfshin mbrojtjet më të fundit të sigurisë dhe privatësisë. Kontrollo për një përditësim ose kontakto zhvilluesin e aplikacionit."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kontrollo për përditësim"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ky aplikacion nuk është i përputhshëm me versionin më të fundit të Android. Kontrollo për një përditësim ose kontakto me zhvilluesin e aplikacionit."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ke mesazhe të reja"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Hap aplikacionin SMS për ta parë"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Disa veçori mund të jenë të kufizuara"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9753ee04e135..ab47275db2b8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -86,7 +86,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можете да упућујете хитне позиве преко Wi‑Fi-ја"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"Обавештења"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"Упозорења"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус мобилних података"</string>
@@ -284,7 +284,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"Мрежа је доступна"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN-а"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"Обавештења од ИТ администратора"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"Обавештења"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"Упозорења"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"Режим демонстрације за малопродајне објекте"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB веза"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ова апликација је направљена за старију верзију Android-а. Можда неће радити исправно и не обухвата најновије безбедносне функције и заштите приватности. Проверите да ли има ажурирања или се обратите програмеру апликације."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ова апликација није компатибилна са најновијом верзијом Android-а. Проверите да ли има ажурирања или се обратите програмеру апликације."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Отворите апликацију за SMS да бисте прегледали"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Неке функције су можда ограничене"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6da10ecb1d2e..871107ad65a8 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g>. Testa med telefonen i stället."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Den här appen byggdes för en äldre version av Android. Den kanske inte fungerar som den ska och har inte de senaste säkerhets- och integritetsskydden. Sök efter en uppdatering eller kontakta appens utvecklare."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sök efter uppdateringar"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Denna app är inte kompatibel med den senaste versionen av Android. Sök efter en uppdatering eller kontakta appens utvecklare."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nya meddelanden"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Öppna sms-appen och visa meddelandet"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Vissa funktioner är begränsade"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2fb0d1710bcc..7c23928c97e7 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Imeshindwa kuunda muundo wa uso wako. Jaribu tena."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Vioo vyeusi vimetambuliwa. Ni lazima uso wako wote uonekane."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Kifuniko cha uso kimetambuliwa. Ni lazima uso wako wote uonekane."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Uso umefunikwa. Lazima uso wako wote uonekane."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Imeshindwa kuthibitisha uso. Maunzi hayapatikani."</string>
@@ -839,7 +839,7 @@
<string-array name="phoneTypes">
<item msgid="8996339953292723951">"Ya nyumbani"</item>
<item msgid="7740243458912727194">"Simu ya mkononi"</item>
- <item msgid="8526146065496663766">"Ya kazini"</item>
+ <item msgid="8526146065496663766">"Kazini"</item>
<item msgid="8150904584178569699">"Pepesi ya Kazini"</item>
<item msgid="4537253139152229577">"Pepesi ya Nyumbani"</item>
<item msgid="6751245029698664340">"Kurasa anwani"</item>
@@ -882,7 +882,7 @@
<string name="phoneTypeCustom" msgid="5120365721260686814">"Maalum"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"Ya nyumbani"</string>
<string name="phoneTypeMobile" msgid="1178852541462086735">"Simu ya mkononi"</string>
- <string name="phoneTypeWork" msgid="6604967163358864607">"Ya kazini"</string>
+ <string name="phoneTypeWork" msgid="6604967163358864607">"Kazini"</string>
<string name="phoneTypeFaxWork" msgid="6757519896109439123">"Pepesi ya Kazini"</string>
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"Pepesi ya Nyumbani"</string>
<string name="phoneTypePager" msgid="576402072263522767">"Peja"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Huwezi kufikia mipangilio hii kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako. Badala yake jaribu kwenye simu yako."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Programu hii ilisanidiwa kwa ajili ya toleo la zamani la Android. Huenda isifanye kazi ipasavyo na haijumuishi ulinzi wa faragha na usalama wa hivi karibuni. Angalia kama ina sasisho au wasiliana na msanidi wa programu."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Angalia masasisho"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Programu hii haitumiki kwenye toleo jipya zaidi la Android. Angalia iwapo sasisho linapatikana au wasiliana na msanidi programu."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Una ujumbe mpya"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Fungua programu ya SMS ili uweze kuangalia"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Huenda baadhi ya vipengele vinadhibitiwa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 915f3acbb105..c6a4530ba469 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1630,7 +1630,7 @@
<string name="media_route_chooser_title" msgid="6646594924991269208">"சாதனத்துடன் இணைக்கவும்"</string>
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ஸ்கிரீனை சாதனத்தில் திரையிடு"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"சாதனங்களைத் தேடுகிறது..."</string>
- <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"அமைப்பு"</string>
+ <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"அமைப்புகள்"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"துண்டி"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"ஸ்கேன் செய்கிறது..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"இணைக்கிறது..."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் மொபைலில் முயன்று பாருங்கள்."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"இந்த ஆப்ஸ் Androidன் பழைய பதிப்பிற்காக உருவாக்கப்பட்டது. இது சரியாகச் செயல்படாமல் போகலாம். மேலும் சமீபத்திய பாதுகாப்பு மற்றும் தனியுரிமை அம்சங்கள் இதில் இல்லை. புதுப்பிப்பு உள்ளதா எனப் பாருங்கள் அல்லது ஆப்ஸ் டெவெலப்பரைத் தொடர்புகொள்ளுங்கள்."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"புதுப்பிப்பு உள்ளதா எனப் பார்"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"இந்த ஆப்ஸ் சமீபத்திய Android பதிப்புடன் இணங்கவில்லை. புதுப்பிப்பு உள்ளதா எனப் பாருங்கள் அல்லது ஆப்ஸ் டெவெலப்பரைத் தொடர்புகொள்ளுங்கள்."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"புதிய செய்திகள் வந்துள்ளன"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"பார்க்க, SMS பயன்பாட்டைத் திறக்கவும்"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"சில செயலுக்கு கட்டுப்பாடு இருக்கலாம்"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"பணிக் கணக்கில் உள்நுழைந்துள்ள <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"தனிப்பட்ட கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"பணிக் கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"பணி ஆப்ஸிலிருந்து அழைக்கவா?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"பணி ஆப்ஸுக்கு மாற வேண்டுமா?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே அழைக்க உங்களை அனுமதிக்கிறது"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே மெசேஜ்களை அனுப்ப உங்களை அனுமதிக்கிறது"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"தனிப்பட்ட உலாவியைப் பயன்படுத்து"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"பணி உலாவியைப் பயன்படுத்து"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"அழை"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"மாற்று"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"சிம் நெட்வொர்க் அன்லாக் பின்"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"சிம் நெட்வொர்க் சப்செட் அன்லாக் பின்"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"கார்ப்பரேட் அன்லாக் பின்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index f0e9201f1dd4..174429cb573e 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -682,7 +682,7 @@
<string name="face_acquired_too_close" msgid="4453646176196302462">"ఫోన్‌ను కాస్త దూరంగా జరపండి"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"ఫోన్‌ను దగ్గరగా పట్టుకోండి"</string>
<string name="face_acquired_too_high" msgid="8278815780046368576">"ఫోన్‌ను పైకి పట్టుకోండి"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"ఫోన్‌ను కిందికి దించండి"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"ఫోన్‌ను కిందికి జరపండి"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"ఫోన్‌ను మీ ఎడమ వైపునకు జరపండి"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"ఫోన్‌ను మీ కుడి వైపునకు జరపండి"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"దయచేసి మీ పరికరం వైపు మరింత నేరుగా చూడండి."</string>
@@ -965,7 +965,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్‌లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్‌లాక్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"అన్‌లాక్ చేయడానికి నమూనాను గీయండి"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"అత్యవసరం"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ఎమర్జెన్సీ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"కాల్‌కు తిరిగి వెళ్లు"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"సరైనది!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"మళ్లీ ట్రై చేయండి"</string>
@@ -1698,11 +1698,11 @@
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>కి మీ పరికరంపై పూర్తి కంట్రోల్‌ను ఇవ్వాలనుకుంటున్నారా?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"అవసరమైన యాక్సెసిబిలిటీ కోసం యాప్‌లకు పూర్తి కంట్రోల్ ఇవ్వడం తగిన పనే అయినా, అన్ని యాప్‌లకు అలా ఇవ్వడం సరికాదు."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"స్క్రీన్‌ను చూసి, కంట్రోల్ చేయగలగడం"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్‌లలో కూడా ఈ కంటెంట్‌ను ప్రదర్శిస్తుంది."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది. అంతే కాక, ఇతర యాప్‌లపై కంటెంట్‌ను డిస్‌ప్లే చేస్తుంది."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్‌‌తో చేసే ఇంటరాక్షన్‌లను లేదా హార్డ్‌వేర్ సెన్సార్‌ను ట్రాక్ చేస్తూ మీ త‌ర‌ఫున యాప్‌లతో ఇంటరాక్ట్ చేయగలదు."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string>
- <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string>
+ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"వద్దు"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్‌ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"వాల్యూమ్ కీ షార్ట్‌కట్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"కలర్ కరెక్షన్"</string>
<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>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరాలు"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>‌ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్‌లో ట్రై చేయండి."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ఈ యాప్ పాత Android వెర్షన్ కోసం రూపొందించబడింది. ఇది సరిగ్గా పని చేయకపోవచ్చు, ఇంకా దీనిలో తాజా సెక్యూరిటీ, గోప్యతా రక్షణలు ఉండకపోవచ్చు. అప్‌డేట్ కోసం చెక్ చేయండి, లేదా యాప్ డెవలపర్‌ను సంప్రదించండి."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ఈ యాప్ Android ఇటీవలి వెర్షన్‌కు అనుకూలంగా లేదు. అప్‌డేట్ కోసం చెక్ చేయండి లేదా యాప్ డెవలపర్‌ను కాంటాక్ట్ చేయండి."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్‌లు ఉన్నాయి"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"చూడటానికి SMS యాప్‌ను తెరవండి"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"కొంత ఫంక్షనాలిటీ పరిమితం కావచ్చు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index bfe85bf2b7a5..e5f76431d357 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"เข้าถึงการตั้งค่านี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"แอปนี้สร้างมาเพื่อ Android เวอร์ชันเก่า ซึ่งอาจทำงานไม่ถูกต้องและไม่มีการคุ้มครองความปลอดภัยและความเป็นส่วนตัวเวอร์ชันล่าสุด ตรวจหาอัปเดตหรือติดต่อนักพัฒนาแอป"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ตรวจสอบอัปเดต"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"แอปนี้ไม่สามารถใช้งานร่วมกับ Android เวอร์ชันล่าสุด ตรวจหาอัปเดตหรือติดต่อนักพัฒนาแอป"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"คุณมีข้อความใหม่"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"เปิดแอป SMS เพื่อดู"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"อาจมีข้อจำกัดในบางฟังก์ชัน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0a1b9a09eda7..1371de6143e9 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>. Subukan na lang sa iyong telepono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ginawa ang app na ito para sa mas lumang bersyon ng Android. Baka hindi ito gumana nang maayos at wala itong pinakabagong proteksyon sa seguridad at privacy. Tingnan kung may update, o makipag-ugnayan sa developer ng app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tingnan kung may update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Hindi compatible ang app sa pinakabagong bersyon ng Android. Tingnan kung may update o makipag-ugnayan sa developer ng app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mayroon kang mga bagong mensahe"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buksan ang SMS app upang tingnan"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Puwedeng limitado ang ilang function"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f5228565807d..af808e8c1bcd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Bu uygulamaya <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu uygulama Android\'in daha eski bir sürümü için geliştirildi. Bu nedenle, düzgün çalışmayabilir ve son güvenlik ile gizlilik korumalarını içermemektedir. Güncelleme olup olmadığını kontrol edin veya uygulamanın geliştiricisiyle iletişime geçin."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncellemeleri denetle"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Görüntülemek için SMS uygulamasını açın"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Bazı işlevler sınırlanabilir"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b5d4bb7cc111..98efe9d4b0f8 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Немає доступу на вашому пристрої (<xliff:g id="DEVICE">%1$s</xliff:g>). Спробуйте натомість скористатися телефоном."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Цей додаток створено для старішої версії ОС Android. Він може не працювати належним чином і не містить найновіших засобів захисту конфіденційності та безпеки. Перевірте наявність оновлень або зв’яжіться з розробником додатка."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шукати оновлення"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас є нові повідомлення"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Щоб переглянути, відкрийте додаток для SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Деякі функції може бути обмежено"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 2cf6b3944754..1f60c9ceff6e 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی حاصل نہیں ہو سکتی۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏یہ ایپ Android کے پرانے ورژن کے لیے بنائی گئی تھی۔ ہو سکتا ہے یہ ٹھیک سے کام نہ کرے اور اس میں تازہ ترین سیکیورٹی اور رازداری کے تحفظات شامل نہ ہوں۔ اپ ڈیٹ کے لیے چیک کریں یا ایپ کے ڈویلپر سے رابطہ کریں۔"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"اپ ڈیٹ چیک کریں"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"آپ کے پاس نئے پیغامات ہیں"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏دیکھنے کیلئے SMS ایپ کھولیں"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"کچھ فعالیت محدود ہو سکتی ہے"</string>
@@ -2165,20 +2167,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"دفتری <xliff:g id="APP">%s</xliff:g> کھولیں؟"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"ذاتی <xliff:g id="APP">%s</xliff:g> میں کھولیں؟"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"دفتری <xliff:g id="APP">%s</xliff:g> میں کھولیں؟"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"ورک ایپ سے کال کریں؟"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ورک ایپ پر سوئچ کریں؟"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"آپ کی تنظیم آپ کو صرف ورک ایپس سے کالز کرنے کی اجازت دیتی ہے"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"آپ کی تنظیم آپ کو صرف ورک ایپس سے پیغامات بھیجنے کی اجازت دیتی ہے"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ذاتی براؤزر استعمال کریں"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"ورک براؤزر استعمال کریں"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"کال کریں"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"سوئچ کریں"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏SIM نیٹ ورک غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏SIM نیٹ ورک سب سیٹ کو غیر مقفل کرنے کا PIN"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏SIM کارپوریٹ کو غیر مقفل کرنے کا PIN"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 154402e0e4ac..0e749faeb8aa 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Bu <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ochilmaydi. Telefon orqali urininb koʻring."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu ilova Androidning eskiroq versiyasiga moʻljallab ishlab chiqilgan. Xatosiz ishlashi mumkin, lekin xavfsizlik va maxfiylik himoyasiga oid oxirgi yangilanishlarini olmaydi. Yangilanish borligini tekshiring yoki ilova ishlab chiquvchisiga murojaat qiling."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Yangilanish borligini tekshirish"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Bu ilova Androidning oxirgi versiyasiga mos emas. Yangilanish borligini tekshiring yoki ilova ishlab chiquvchisiga murojaat qiling."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sizga yangi SMS keldi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ko‘rish uchun SMS ilovasini oching"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Ayrim funksiyalar ishlamasligi mumkin"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 628f02abfeca..ac4358ba717e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên điện thoại."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ứng dụng này được xây dựng cho một phiên bản Android cũ. Ứng dụng này có thể không hoạt động đúng cách và không có các biện pháp bảo vệ mới nhất về bảo mật và quyền riêng tư. Hãy kiểm tra để tìm bản cập nhật hoặc liên hệ với nhà phát triển của ứng dụng."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kiểm tra để tìm bản cập nhật"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ứng dụng này không tương thích với phiên bản Android mới nhất. Hãy kiểm tra để tìm bản cập nhật hoặc liên hệ với nhà phát triển của ứng dụng."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Bạn có tin nhắn mới"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Mở ứng dụng SMS để xem"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Một số chức năng có thể bị hạn chế"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4f783e8cd2cd..e938fbfa1a66 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"无法创建您的脸部模型,请重试。"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"检测到墨镜,您的脸部必须完全可见。"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到脸部有遮挡物,您的脸部必须完全可见。"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到脸部存在遮挡,请露出整张脸。"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"无法验证人脸。硬件无法使用。"</string>
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"色彩校正"</string>
<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>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听装置"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
@@ -1937,7 +1937,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"添加受监管用户"</string>
<string name="language_selection_title" msgid="52674936078683285">"添加语言"</string>
- <string name="country_selection_title" msgid="5221495687299014379">"区域偏好设置"</string>
+ <string name="country_selection_title" msgid="5221495687299014379">"地区偏好设置"</string>
<string name="search_language_hint" msgid="7004225294308793583">"输入语言名称"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"建议语言"</string>
<string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"推荐地区"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此设置,您可以尝试在手机上访问。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此应用专为旧版 Android 系统打造。它可能无法正常运行,也不包含最新的安全和隐私保护功能。请检查是否有更新,或与应用开发者联系。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"检查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"此应用与最新版 Android 不兼容。请检查是否有更新,或与应用开发者联系。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"您有新消息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"打开短信应用查看"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能会受到限制"</string>
@@ -1984,7 +1985,7 @@
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"点按即可查看文件"</string>
<string name="pin_target" msgid="8036028973110156895">"置顶"</string>
<string name="pin_specific_target" msgid="7824671240625957415">"将<xliff:g id="LABEL">%1$s</xliff:g>置顶"</string>
- <string name="unpin_target" msgid="3963318576590204447">"取消固定"</string>
+ <string name="unpin_target" msgid="3963318576590204447">"取消置顶"</string>
<string name="unpin_specific_target" msgid="3859828252160908146">"取消置顶<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"应用信息"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 997f963ce802..69bf3f358140 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1695,7 +1695,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"不要開啟"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"開啟"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"關閉"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要授予「<xliff:g id="SERVICE">%1$s</xliff:g>」裝置的完整控制權?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要授予「<xliff:g id="SERVICE">%1$s</xliff:g>」裝置的完整控制權嗎?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"對於為你提供無障礙功能的應用程式,你可授予完整控制權,但大部分應用程式都不應獲授予此權限。"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"查看和控制螢幕"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"這項功能可以讀出螢幕上的所有內容,並透過其他應用程式顯示內容。"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此應用程式專為舊版 Android 而設。因此可能無法正常運作,且不提供最新的安全性和私隱保護。請檢查是否有更新版本,或聯絡應用程式開發人員。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"這個應用程式與最新版的 Android 不相容。請檢查是否有可用的更新,或與應用程式發人員聯絡。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"你有新的訊息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"開啟短訊應用程式查看內容"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能會受到限制"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index cf03b28c4371..5b647fac3ca2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"這個應用程式是專為舊版 Android 所打造,因此可能無法正常運作,且不提供最新的安全性和隱私保護服務。請檢查是否有更新版本,或與應用程式的開發人員聯絡。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"這個應用程式與最新版的 Android 不相容。請檢查是否有可用的更新,或與應用程式發人員聯絡。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"你有新訊息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"開啟簡訊應用程式來查看內容"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能遭到鎖定"</string>
@@ -2165,20 +2166,14 @@
<string name="miniresolver_open_work" msgid="6286176185835401931">"要開啟工作用「<xliff:g id="APP">%s</xliff:g>」嗎?"</string>
<string name="miniresolver_open_in_personal" msgid="807427577794490375">"要在個人用「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
<string name="miniresolver_open_in_work" msgid="941341494673509916">"要在工作用「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
- <!-- no translation found for miniresolver_call_in_work (528779988307529039) -->
- <skip />
- <!-- no translation found for miniresolver_switch_to_work (1042640606122638596) -->
- <skip />
- <!-- no translation found for miniresolver_call_information (6739417525304184083) -->
- <skip />
- <!-- no translation found for miniresolver_sms_information (4311292661329483088) -->
- <skip />
+ <string name="miniresolver_call_in_work" msgid="528779988307529039">"要透過工作應用程式撥號嗎?"</string>
+ <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"要切換到工作應用程式嗎?"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"貴機構僅允許透過工作應用程式撥打電話"</string>
+ <string name="miniresolver_sms_information" msgid="4311292661329483088">"貴機構僅允許透過工作應用程式傳送訊息"</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
- <!-- no translation found for miniresolver_call (6386870060423480765) -->
- <skip />
- <!-- no translation found for miniresolver_switch (8011924662117617451) -->
- <skip />
+ <string name="miniresolver_call" msgid="6386870060423480765">"撥號"</string>
+ <string name="miniresolver_switch" msgid="8011924662117617451">"切換"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 卡網路解鎖 PIN 碼"</string>
<string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM 卡網路子集解鎖 PIN 碼"</string>
<string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM 卡企業解鎖 PIN 碼"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index b2ef74a5b5d6..e432c69d36de 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Lokhu akukwazi ukufinyelelwa ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho. Zama efonini yakho kunalokho."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Le app yakhelwe uhlobo lwakudala le-Android. Ingase ingasebenzi kahle futhi ayinakho ukuvikeleka kwakamuva nokuvikelwa kobumfihlo. Hlola isibuyekezo, noma uthinte unjiniyela we-app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Hlola izibuyekezo"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Le app ayihambisani nohlobo lwakamuva lwe-Android. Hlola isibuyekezo, noma uthinte unjiniyela we-app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Unemilayezo emisha"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Vula uhlelo lokusebenza lwe-SMS ukuze ubuke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Okunye ukusebenza kungakhawulelwe"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 114cea16980c..8473f9bc8d0b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4429,6 +4429,14 @@
-->
<string name="config_defaultContentCaptureService" translatable="false"></string>
+ <!-- The package name for the system's content protection service.
+ This service must be trusted, as it can be activated without explicit consent of the user.
+ If no service with the specified name exists on the device, content protection will be
+ disabled.
+ Example: "com.android.contentprotection/.ContentProtectionService"
+ -->
+ <string name="config_defaultContentProtectionService" translatable="false"></string>
+
<!-- The package name for the system's augmented autofill service.
This service must be trusted, as it can be activated without explicit consent of the user.
If no service with the specified name exists on the device, augmented autofill wil be
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 91fbf6bb9f06..fb3acbe79114 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5410,6 +5410,9 @@
<!-- Title for button to see application detail in app store which it came from - it may allow user to update to newer version. [CHAR LIMIT=50] -->
<string name="deprecated_target_sdk_app_store">Check for update</string>
+ <!-- Message displayed in dialog when app is 32 bit on a 64 bit system. [CHAR LIMIT=NONE] -->
+ <string name="deprecated_abi_message">This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.</string>
+
<!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
<string name="new_sms_notification_title">You have new messages</string>
<!-- Notification content shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a4643d0af84e..94225926896b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3156,6 +3156,8 @@
<java-symbol type="string" name="deprecated_target_sdk_message" />
<java-symbol type="string" name="deprecated_target_sdk_app_store" />
+ <java-symbol type="string" name="deprecated_abi_message" />
+
<!-- New SMS notification while phone is locked. -->
<java-symbol type="string" name="new_sms_notification_title" />
<java-symbol type="string" name="new_sms_notification_content" />
@@ -3761,6 +3763,7 @@
<java-symbol type="string" name="config_defaultTextClassifierPackage" />
<java-symbol type="string" name="config_defaultWellbeingPackage" />
<java-symbol type="string" name="config_defaultContentCaptureService" />
+ <java-symbol type="string" name="config_defaultContentProtectionService" />
<java-symbol type="string" name="config_defaultAugmentedAutofillService" />
<java-symbol type="string" name="config_defaultTranslationService" />
<java-symbol type="string" name="config_defaultAppPredictionService" />
diff --git a/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java
index 81eb213ce78a..5ac99db3aea5 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityManagerTest.java
@@ -128,6 +128,7 @@ public class ActivityManagerTest extends AndroidTestCase {
0x222222, // colorBackground
0x333333, // statusBarColor
0x444444, // navigationBarColor
+ 0, // statusBarAppearance
true, // ensureStatusBarContrastWhenTransparent
true, // ensureNavigationBarContrastWhenTransparent
RESIZE_MODE_RESIZEABLE, // resizeMode
@@ -152,6 +153,7 @@ public class ActivityManagerTest extends AndroidTestCase {
0x222222, // colorBackground
0x333333, // statusBarColor
0x444444, // navigationBarColor
+ 0, // statusBarAppearance
false, // ensureStatusBarContrastWhenTransparent
false, // ensureNavigationBarContrastWhenTransparent
RESIZE_MODE_UNRESIZEABLE, // resizeMode
@@ -167,6 +169,7 @@ public class ActivityManagerTest extends AndroidTestCase {
0x2222222, // colorBackground
0x3333332, // statusBarColor
0x4444442, // navigationBarColor
+ 0, // statusBarAppearance
true, // ensureStatusBarContrastWhenTransparent
true, // ensureNavigationBarContrastWhenTransparent
RESIZE_MODE_RESIZEABLE, // resizeMode
@@ -197,6 +200,7 @@ public class ActivityManagerTest extends AndroidTestCase {
0x222222, // colorBackground
0x333333, // statusBarColor
0x444444, // navigationBarColor
+ 0, // statusBarAppearance
false, // ensureStatusBarContrastWhenTransparent
false, // ensureNavigationBarContrastWhenTransparent
RESIZE_MODE_UNRESIZEABLE, // resizeMode
@@ -219,6 +223,7 @@ public class ActivityManagerTest extends AndroidTestCase {
0x222222, // colorBackground
0x333333, // statusBarColor
0x444444, // navigationBarColor
+ 0, // statusBarAppearance
false, // ensureStatusBarContrastWhenTransparent
false, // ensureNavigationBarContrastWhenTransparent
RESIZE_MODE_UNRESIZEABLE, // resizeMode
@@ -250,6 +255,7 @@ public class ActivityManagerTest extends AndroidTestCase {
assertEquals(td1.getBackgroundColor(), td2.getBackgroundColor());
assertEquals(td1.getStatusBarColor(), td2.getStatusBarColor());
assertEquals(td1.getNavigationBarColor(), td2.getNavigationBarColor());
+ assertEquals(td1.getStatusBarAppearance(), td2.getStatusBarAppearance());
assertEquals(td1.getResizeMode(), td2.getResizeMode());
assertEquals(td1.getMinWidth(), td2.getMinWidth());
assertEquals(td1.getMinHeight(), td2.getMinHeight());
diff --git a/core/tests/coretests/src/android/content/ContentCaptureOptionsTest.java b/core/tests/coretests/src/android/content/ContentCaptureOptionsTest.java
index c6f4fa27dc83..f8348d28b7fe 100644
--- a/core/tests/coretests/src/android/content/ContentCaptureOptionsTest.java
+++ b/core/tests/coretests/src/android/content/ContentCaptureOptionsTest.java
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Parcel;
import android.util.ArraySet;
import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
@@ -40,16 +41,29 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ContentCaptureOptionsTest {
- private final ComponentName mContextComponent = new ComponentName("marco", "polo");
- private final ComponentName mComp1 = new ComponentName("comp", "one");
- private final ComponentName mComp2 = new ComponentName("two", "comp");
+ private static final ComponentName CONTEXT_COMPONENT = new ComponentName("marco", "polo");
+ private static final ComponentName COMPONENT1 = new ComponentName("comp", "one");
+ private static final ComponentName COMPONENT2 = new ComponentName("two", "comp");
+ private static final ContentCaptureOptions CONTENT_CAPTURE_OPTIONS =
+ new ContentCaptureOptions(
+ /* loggingLevel= */ 1000,
+ /* maxBufferSize= */ 1001,
+ /* idleFlushingFrequencyMs= */ 1002,
+ /* textChangeFlushingFrequencyMs= */ 1003,
+ /* logHistorySize= */ 1004,
+ /* disableFlushForViewTreeAppearing= */ true,
+ /* enableReceiver= */ false,
+ new ContentCaptureOptions.ContentProtectionOptions(
+ /* enableReceiver= */ true,
+ /* bufferSize= */ 2001),
+ /* whitelistedComponents= */ toSet(COMPONENT1, COMPONENT2));
@Mock private Context mContext;
@Mock private ContentCaptureClient mClient;
@Before
public void setExpectation() {
- when(mClient.contentCaptureClientGetComponentName()).thenReturn(mContextComponent);
+ when(mClient.contentCaptureClientGetComponentName()).thenReturn(CONTEXT_COMPONENT);
when(mContext.getContentCaptureClient()).thenReturn(mClient);
}
@@ -67,26 +81,27 @@ public class ContentCaptureOptionsTest {
@Test
public void testIsWhitelisted_notWhitelisted() {
- ContentCaptureOptions options = new ContentCaptureOptions(toSet(mComp1, mComp2));
+ ContentCaptureOptions options = new ContentCaptureOptions(toSet(COMPONENT1, COMPONENT2));
assertThat(options.isWhitelisted(mContext)).isFalse();
}
@Test
public void testIsWhitelisted_whitelisted() {
- ContentCaptureOptions options = new ContentCaptureOptions(toSet(mComp1, mContextComponent));
+ ContentCaptureOptions options =
+ new ContentCaptureOptions(toSet(COMPONENT1, CONTEXT_COMPONENT));
assertThat(options.isWhitelisted(mContext)).isTrue();
}
@Test
public void testIsWhitelisted_invalidContext() {
- ContentCaptureOptions options = new ContentCaptureOptions(toSet(mContextComponent));
+ ContentCaptureOptions options = new ContentCaptureOptions(toSet(CONTEXT_COMPONENT));
Context invalidContext = mock(Context.class); // has no client
assertThat(options.isWhitelisted(invalidContext)).isFalse();
}
@Test
public void testIsWhitelisted_clientWithNullComponentName() {
- ContentCaptureOptions options = new ContentCaptureOptions(toSet(mContextComponent));
+ ContentCaptureOptions options = new ContentCaptureOptions(toSet(CONTEXT_COMPONENT));
ContentCaptureClient client = mock(ContentCaptureClient.class);
Context context = mock(Context.class);
when(context.getContentCaptureClient()).thenReturn(client);
@@ -94,8 +109,69 @@ public class ContentCaptureOptionsTest {
assertThat(options.isWhitelisted(context)).isFalse();
}
+ @Test
+ public void testToString() {
+ String actual = CONTENT_CAPTURE_OPTIONS.toString();
+
+ String expected =
+ new StringBuilder("ContentCaptureOptions [")
+ .append("loggingLevel=")
+ .append(CONTENT_CAPTURE_OPTIONS.loggingLevel)
+ .append(", maxBufferSize=")
+ .append(CONTENT_CAPTURE_OPTIONS.maxBufferSize)
+ .append(", idleFlushingFrequencyMs=")
+ .append(CONTENT_CAPTURE_OPTIONS.idleFlushingFrequencyMs)
+ .append(", textChangeFlushingFrequencyMs=")
+ .append(CONTENT_CAPTURE_OPTIONS.textChangeFlushingFrequencyMs)
+ .append(", logHistorySize=")
+ .append(CONTENT_CAPTURE_OPTIONS.logHistorySize)
+ .append(", disableFlushForViewTreeAppearing=")
+ .append(CONTENT_CAPTURE_OPTIONS.disableFlushForViewTreeAppearing)
+ .append(", enableReceiver=")
+ .append(CONTENT_CAPTURE_OPTIONS.enableReceiver)
+ .append(", contentProtectionOptions=ContentProtectionOptions [")
+ .append("enableReceiver=")
+ .append(CONTENT_CAPTURE_OPTIONS.contentProtectionOptions.enableReceiver)
+ .append(", bufferSize=")
+ .append(CONTENT_CAPTURE_OPTIONS.contentProtectionOptions.bufferSize)
+ .append("], whitelisted=")
+ .append(CONTENT_CAPTURE_OPTIONS.whitelistedComponents)
+ .append(']')
+ .toString();
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ @Test
+ public void testParcelSerializationDeserialization() {
+ Parcel parcel = Parcel.obtain();
+ CONTENT_CAPTURE_OPTIONS.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+
+ ContentCaptureOptions actual = ContentCaptureOptions.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+
+ assertThat(actual).isNotNull();
+ assertThat(actual.loggingLevel).isEqualTo(CONTENT_CAPTURE_OPTIONS.loggingLevel);
+ assertThat(actual.maxBufferSize).isEqualTo(CONTENT_CAPTURE_OPTIONS.maxBufferSize);
+ assertThat(actual.idleFlushingFrequencyMs)
+ .isEqualTo(CONTENT_CAPTURE_OPTIONS.idleFlushingFrequencyMs);
+ assertThat(actual.textChangeFlushingFrequencyMs)
+ .isEqualTo(CONTENT_CAPTURE_OPTIONS.textChangeFlushingFrequencyMs);
+ assertThat(actual.logHistorySize).isEqualTo(CONTENT_CAPTURE_OPTIONS.logHistorySize);
+ assertThat(actual.disableFlushForViewTreeAppearing)
+ .isEqualTo(CONTENT_CAPTURE_OPTIONS.disableFlushForViewTreeAppearing);
+ assertThat(actual.enableReceiver).isEqualTo(CONTENT_CAPTURE_OPTIONS.enableReceiver);
+ assertThat(actual.contentProtectionOptions).isNotNull();
+ assertThat(actual.contentProtectionOptions.enableReceiver)
+ .isEqualTo(CONTENT_CAPTURE_OPTIONS.contentProtectionOptions.enableReceiver);
+ assertThat(actual.contentProtectionOptions.bufferSize)
+ .isEqualTo(CONTENT_CAPTURE_OPTIONS.contentProtectionOptions.bufferSize);
+ assertThat(actual.whitelistedComponents)
+ .containsExactlyElementsIn(CONTENT_CAPTURE_OPTIONS.whitelistedComponents);
+ }
+
@NonNull
- private ArraySet<ComponentName> toSet(@Nullable ComponentName... comps) {
+ private static ArraySet<ComponentName> toSet(@Nullable ComponentName... comps) {
ArraySet<ComponentName> set = new ArraySet<>();
if (comps != null) {
for (int i = 0; i < comps.length; i++) {
diff --git a/core/tests/coretests/src/android/content/OWNERS b/core/tests/coretests/src/android/content/OWNERS
index a69c6ffef8d8..6f38b848853b 100644
--- a/core/tests/coretests/src/android/content/OWNERS
+++ b/core/tests/coretests/src/android/content/OWNERS
@@ -5,3 +5,5 @@ per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS
per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
per-file *ComponentCallbacks* = file:/services/core/java/com/android/server/wm/OWNERS
per-file *ComponentCallbacks* = charlesccchen@google.com
+per-file ContentCaptureOptions* = file:/core/java/android/view/contentcapture/OWNERS
+
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
index 6e8e93a8c86b..b2e42ba90152 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
@@ -26,6 +26,7 @@ import android.app.Activity;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Bundle;
import android.platform.test.annotations.IwTest;
+import android.platform.test.annotations.PlatinumTest;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.util.PollingCheck;
@@ -72,6 +73,7 @@ public class FontScaleConverterActivityTest {
restoreSystemFontScaleToDefault();
}
+ @PlatinumTest(focusArea = "accessibility")
@IwTest(focusArea = "accessibility")
@Test
public void testFontsScaleNonLinearly() {
@@ -103,6 +105,7 @@ public class FontScaleConverterActivityTest {
)));
}
+ @PlatinumTest(focusArea = "accessibility")
@IwTest(focusArea = "accessibility")
@Test
public void testOnConfigurationChanged_doesNotCrash() {
@@ -117,6 +120,7 @@ public class FontScaleConverterActivityTest {
});
}
+ @PlatinumTest(focusArea = "accessibility")
@IwTest(focusArea = "accessibility")
@Test
public void testUpdateConfiguration_doesNotCrash() {
diff --git a/core/tests/coretests/src/android/content/res/TEST_MAPPING b/core/tests/coretests/src/android/content/res/TEST_MAPPING
index ab14950891c3..4ea6e40a7225 100644
--- a/core/tests/coretests/src/android/content/res/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/res/TEST_MAPPING
@@ -39,18 +39,5 @@
}
]
}
- ],
- "ironwood-postsubmit": [
- {
- "name": "FrameworksCoreTests",
- "options":[
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
]
}
diff --git a/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java b/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java
index d10ba7ccbac4..e117051ba9de 100644
--- a/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java
+++ b/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java
@@ -104,6 +104,18 @@ public class SurfaceControlRegistryTests {
}
@Test
+ public void testInvalidSurfaceControlNotAddedToRegistry() {
+ int hash0 = SurfaceControlRegistry.getProcessInstance().hashCode();
+ // Verify no changes to the registry when dealing with invalid surface controls
+ SurfaceControl sc0 = new SurfaceControl();
+ SurfaceControl sc1 = new SurfaceControl(sc0, "test");
+ assertEquals(hash0, SurfaceControlRegistry.getProcessInstance().hashCode());
+ sc0.release();
+ sc1.release();
+ assertEquals(hash0, SurfaceControlRegistry.getProcessInstance().hashCode());
+ }
+
+ @Test
public void testThresholds() {
SurfaceControlRegistry registry = SurfaceControlRegistry.getProcessInstance();
TestReporter reporter = new TestReporter();
diff --git a/core/tests/coretests/src/android/view/contentprotection/ContentProtectionUtilsTest.java b/core/tests/coretests/src/android/view/contentprotection/ContentProtectionUtilsTest.java
new file mode 100644
index 000000000000..1459799adee5
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentprotection/ContentProtectionUtilsTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.contentprotection;
+
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.View;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ViewNode;
+import android.view.contentcapture.ViewNode.ViewStructureImpl;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for {@link ContentProtectionUtils}.
+ *
+ * <p>Run with: {@code atest
+ * FrameworksCoreTests:android.view.contentprotection.ContentProtectionUtilsTest}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ContentProtectionUtilsTest {
+
+ private static final String TEXT = "TEST_TEXT";
+
+ private static final ContentCaptureEvent EVENT = createEvent();
+
+ private static final ViewNode VIEW_NODE = new ViewNode();
+
+ private static final ViewNode VIEW_NODE_WITH_TEXT = createViewNodeWithText();
+
+ @Test
+ public void event_getEventText_null() {
+ String actual = ContentProtectionUtils.getEventText(EVENT);
+
+ assertThat(actual).isNull();
+ }
+
+ @Test
+ public void event_getEventText_notNull() {
+ ContentCaptureEvent event = createEvent();
+ event.setText(TEXT);
+
+ String actual = ContentProtectionUtils.getEventText(event);
+
+ assertThat(actual).isEqualTo(TEXT);
+ }
+
+ @Test
+ public void event_getViewNodeText_null() {
+ String actual = ContentProtectionUtils.getViewNodeText(EVENT);
+
+ assertThat(actual).isNull();
+ }
+
+ @Test
+ public void event_getViewNodeText_notNull() {
+ ContentCaptureEvent event = createEvent();
+ event.setViewNode(VIEW_NODE_WITH_TEXT);
+
+ String actual = ContentProtectionUtils.getViewNodeText(event);
+
+ assertThat(actual).isEqualTo(TEXT);
+ }
+
+ @Test
+ public void viewNode_getViewNodeText_null() {
+ String actual = ContentProtectionUtils.getViewNodeText(VIEW_NODE);
+
+ assertThat(actual).isNull();
+ }
+
+ @Test
+ public void viewNode_getViewNodeText_notNull() {
+ String actual = ContentProtectionUtils.getViewNodeText(VIEW_NODE_WITH_TEXT);
+
+ assertThat(actual).isEqualTo(TEXT);
+ }
+
+ private static ContentCaptureEvent createEvent() {
+ return new ContentCaptureEvent(/* sessionId= */ 123, TYPE_SESSION_STARTED);
+ }
+
+ private static ViewNode createViewNodeWithText() {
+ View view = new View(ApplicationProvider.getApplicationContext());
+ ViewStructureImpl viewStructure = new ViewStructureImpl(view);
+ viewStructure.setText(TEXT);
+ return viewStructure.getNode();
+ }
+}
diff --git a/core/tests/coretests/src/android/view/contentprotection/OWNERS b/core/tests/coretests/src/android/view/contentprotection/OWNERS
new file mode 100644
index 000000000000..b3583a7f6ab1
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentprotection/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 544200
+
+include /core/java/android/view/contentcapture/OWNERS
+
diff --git a/core/tests/coretests/src/android/view/inputmethod/TextAppearanceInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/TextAppearanceInfoTest.java
index f93cd18a8521..0750cf1a64ab 100644
--- a/core/tests/coretests/src/android/view/inputmethod/TextAppearanceInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/TextAppearanceInfoTest.java
@@ -37,6 +37,7 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.ScaleXSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
+import android.text.util.Linkify;
import android.view.ViewGroup;
import android.widget.EditText;
@@ -53,7 +54,7 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class TextAppearanceInfoTest {
private static final float EPSILON = 0.0000001f;
- private static final String TEST_TEXT = "Happy birthday!";
+ private static final String TEST_TEXT = "Hello: google.com";
private static final float TEXT_SIZE = 16.5f;
private static final LocaleList TEXT_LOCALES = LocaleList.forLanguageTags("en,ja");
private static final String FONT_FAMILY_NAME = "sans-serif";
@@ -84,39 +85,7 @@ public class TextAppearanceInfoTest {
@Before
public void setUp() {
- mEditText.setText(mSpannableText);
- mEditText.getPaint().setTextSize(TEXT_SIZE);
- mEditText.setTextLocales(TEXT_LOCALES);
- Typeface family = Typeface.create(FONT_FAMILY_NAME, Typeface.NORMAL);
- mEditText.setTypeface(
- Typeface.create(family, TEXT_WEIGHT, (TEXT_STYLE & Typeface.ITALIC) != 0));
- mEditText.setAllCaps(ALL_CAPS);
- mEditText.setShadowLayer(SHADOW_RADIUS, SHADOW_DX, SHADOW_DY, SHADOW_COLOR);
- mEditText.setElegantTextHeight(ELEGANT_TEXT_HEIGHT);
- mEditText.setFallbackLineSpacing(FALLBACK_LINE_SPACING);
- mEditText.setLetterSpacing(LETTER_SPACING);
- mEditText.setFontFeatureSettings(FONT_FEATURE_SETTINGS);
- mEditText.setFontVariationSettings(FONT_VARIATION_SETTINGS);
- mEditText.setLineBreakStyle(LINE_BREAK_STYLE);
- mEditText.setLineBreakWordStyle(LINE_BREAK_WORD_STYLE);
- mEditText.setTextScaleX(TEXT_SCALEX);
- mEditText.setHighlightColor(HIGHLIGHT_TEXT_COLOR);
- mEditText.setTextColor(TEXT_COLOR);
- mEditText.setHintTextColor(HINT_TEXT_COLOR);
- mEditText.setLinkTextColor(LINK_TEXT_COLOR);
- ViewGroup.LayoutParams params =
- new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- mEditText.setLayoutParams(params);
- mEditText.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- Bitmap bitmap =
- Bitmap.createBitmap(
- Math.max(1, mEditText.getMeasuredWidth()),
- Math.max(1, mEditText.getMeasuredHeight()),
- Bitmap.Config.ARGB_8888);
- mEditText.layout(0, 0, mEditText.getMeasuredWidth(), mEditText.getMeasuredHeight());
- mCanvas = new Canvas(bitmap);
- mEditText.draw(mCanvas);
+ initEditText(mSpannableText);
}
@Test
@@ -233,6 +202,43 @@ public class TextAppearanceInfoTest {
assertEquals(info1.getSystemFontFamilyName(), FONT_FAMILY_NAME);
}
+ private void initEditText(CharSequence text) {
+ mEditText.setText(text);
+ mEditText.getPaint().setTextSize(TEXT_SIZE);
+ mEditText.setTextLocales(TEXT_LOCALES);
+ Typeface family = Typeface.create(FONT_FAMILY_NAME, Typeface.NORMAL);
+ mEditText.setTypeface(
+ Typeface.create(family, TEXT_WEIGHT, (TEXT_STYLE & Typeface.ITALIC) != 0));
+ mEditText.setAllCaps(ALL_CAPS);
+ mEditText.setShadowLayer(SHADOW_RADIUS, SHADOW_DX, SHADOW_DY, SHADOW_COLOR);
+ mEditText.setElegantTextHeight(ELEGANT_TEXT_HEIGHT);
+ mEditText.setFallbackLineSpacing(FALLBACK_LINE_SPACING);
+ mEditText.setLetterSpacing(LETTER_SPACING);
+ mEditText.setFontFeatureSettings(FONT_FEATURE_SETTINGS);
+ mEditText.setFontVariationSettings(FONT_VARIATION_SETTINGS);
+ mEditText.setLineBreakStyle(LINE_BREAK_STYLE);
+ mEditText.setLineBreakWordStyle(LINE_BREAK_WORD_STYLE);
+ mEditText.setTextScaleX(TEXT_SCALEX);
+ mEditText.setHighlightColor(HIGHLIGHT_TEXT_COLOR);
+ mEditText.setTextColor(TEXT_COLOR);
+ mEditText.setHintTextColor(HINT_TEXT_COLOR);
+ mEditText.setHint("Hint text");
+ mEditText.setLinkTextColor(LINK_TEXT_COLOR);
+ mEditText.setAutoLinkMask(Linkify.WEB_URLS);
+ ViewGroup.LayoutParams params =
+ new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mEditText.setLayoutParams(params);
+ mEditText.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ Bitmap bitmap =
+ Bitmap.createBitmap(
+ Math.max(1, mEditText.getMeasuredWidth()),
+ Math.max(1, mEditText.getMeasuredHeight()),
+ Bitmap.Config.ARGB_8888);
+ mEditText.layout(0, 0, mEditText.getMeasuredWidth(), mEditText.getMeasuredHeight());
+ mCanvas = new Canvas(bitmap);
+ mEditText.draw(mCanvas);
+ }
private void assertTextAppearanceInfoContentsEqual(TextAppearanceInfo textAppearanceInfo) {
assertEquals(textAppearanceInfo.getTextSize(), TEXT_SIZE, EPSILON);
assertEquals(textAppearanceInfo.getTextLocales(), TEXT_LOCALES);
@@ -258,6 +264,15 @@ public class TextAppearanceInfoTest {
assertEquals(textAppearanceInfo.getLinkTextColor(), LINK_TEXT_COLOR);
}
+ @Test
+ public void testCreateFromTextView_withHintText() {
+ // Make hint text display
+ initEditText("");
+
+ // The text color should not be hint color
+ assertTextAppearanceInfoContentsEqual(TextAppearanceInfo.createFromTextView(mEditText));
+ }
+
static class CustomForegroundColorSpan extends ForegroundColorSpan {
@Nullable public TextPaint lastTextPaint = null;
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 467222696dfb..73aa93603e56 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -58,6 +58,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@@ -716,6 +717,43 @@ public class RemoteViewsTest {
}
@Test
+ public void visitUris_themedIcons() {
+ RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
+ final Icon iconLight = Icon.createWithContentUri("content://light/icon");
+ final Icon iconDark = Icon.createWithContentUri("content://dark/icon");
+ views.setIcon(R.id.layout, "setLargeIcon", iconLight, iconDark);
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ views.visitUris(visitor);
+ verify(visitor, times(1)).accept(eq(iconLight.getUri()));
+ verify(visitor, times(1)).accept(eq(iconDark.getUri()));
+ }
+
+ @Test
+ public void visitUris_nestedViews() {
+ final RemoteViews outer = new RemoteViews(mPackage, R.layout.remote_views_test);
+
+ final RemoteViews inner = new RemoteViews(mPackage, 33);
+ final Uri imageUriI = Uri.parse("content://inner/image");
+ final Icon icon1 = Icon.createWithContentUri("content://inner/icon1");
+ final Icon icon2 = Icon.createWithContentUri("content://inner/icon2");
+ final Icon icon3 = Icon.createWithContentUri("content://inner/icon3");
+ final Icon icon4 = Icon.createWithContentUri("content://inner/icon4");
+ inner.setImageViewUri(R.id.image, imageUriI);
+ inner.setTextViewCompoundDrawables(R.id.text, icon1, icon2, icon3, icon4);
+
+ outer.addView(R.id.layout, inner);
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ outer.visitUris(visitor);
+ verify(visitor, times(1)).accept(eq(imageUriI));
+ verify(visitor, times(1)).accept(eq(icon1.getUri()));
+ verify(visitor, times(1)).accept(eq(icon2.getUri()));
+ verify(visitor, times(1)).accept(eq(icon3.getUri()));
+ verify(visitor, times(1)).accept(eq(icon4.getUri()));
+ }
+
+ @Test
public void visitUris_separateOrientation() {
final RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test);
final Uri imageUriL = Uri.parse("content://landscape/image");
@@ -750,4 +788,43 @@ public class RemoteViewsTest {
verify(visitor, times(1)).accept(eq(icon3P.getUri()));
verify(visitor, times(1)).accept(eq(icon4P.getUri()));
}
+
+ @Test
+ public void visitUris_sizedViews() {
+ final RemoteViews large = new RemoteViews(mPackage, R.layout.remote_views_test);
+ final Uri imageUriL = Uri.parse("content://large/image");
+ final Icon icon1L = Icon.createWithContentUri("content://large/icon1");
+ final Icon icon2L = Icon.createWithContentUri("content://large/icon2");
+ final Icon icon3L = Icon.createWithContentUri("content://large/icon3");
+ final Icon icon4L = Icon.createWithContentUri("content://large/icon4");
+ large.setImageViewUri(R.id.image, imageUriL);
+ large.setTextViewCompoundDrawables(R.id.text, icon1L, icon2L, icon3L, icon4L);
+
+ final RemoteViews small = new RemoteViews(mPackage, 33);
+ final Uri imageUriS = Uri.parse("content://small/image");
+ final Icon icon1S = Icon.createWithContentUri("content://small/icon1");
+ final Icon icon2S = Icon.createWithContentUri("content://small/icon2");
+ final Icon icon3S = Icon.createWithContentUri("content://small/icon3");
+ final Icon icon4S = Icon.createWithContentUri("content://small/icon4");
+ small.setImageViewUri(R.id.image, imageUriS);
+ small.setTextViewCompoundDrawables(R.id.text, icon1S, icon2S, icon3S, icon4S);
+
+ HashMap<SizeF, RemoteViews> sizedViews = new HashMap<>();
+ sizedViews.put(new SizeF(300, 300), large);
+ sizedViews.put(new SizeF(100, 100), small);
+ RemoteViews views = new RemoteViews(sizedViews);
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ views.visitUris(visitor);
+ verify(visitor, times(1)).accept(eq(imageUriL));
+ verify(visitor, times(1)).accept(eq(icon1L.getUri()));
+ verify(visitor, times(1)).accept(eq(icon2L.getUri()));
+ verify(visitor, times(1)).accept(eq(icon3L.getUri()));
+ verify(visitor, times(1)).accept(eq(icon4L.getUri()));
+ verify(visitor, times(1)).accept(eq(imageUriS));
+ verify(visitor, times(1)).accept(eq(icon1S.getUri()));
+ verify(visitor, times(1)).accept(eq(icon2S.getUri()));
+ verify(visitor, times(1)).accept(eq(icon3S.getUri()));
+ verify(visitor, times(1)).accept(eq(icon4S.getUri()));
+ }
}
diff --git a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
index 281d677dccb0..036154634ae7 100644
--- a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
+++ b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
@@ -88,6 +88,7 @@ public class SnapshotDrawerUtilsTest {
1, HardwareBuffer.USAGE_CPU_READ_RARELY);
return new TaskSnapshot(
System.currentTimeMillis(),
+ 0 /* captureTime */,
new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
@@ -157,32 +158,42 @@ public class SnapshotDrawerUtilsTest {
@Test
public void testCalculateSnapshotCrop() {
- setupSurface(100, 100, new Rect(0, 10, 0, 10), 0, new Rect(0, 0, 100, 100));
- assertEquals(new Rect(0, 0, 100, 90), mSnapshotSurface.calculateSnapshotCrop());
+ final Rect contentInsets = new Rect(0, 10, 0, 10);
+ setupSurface(100, 100, contentInsets, 0, new Rect(0, 0, 100, 100));
+ assertEquals(new Rect(0, 0, 100, 90),
+ mSnapshotSurface.calculateSnapshotCrop(contentInsets));
}
@Test
public void testCalculateSnapshotCrop_taskNotOnTop() {
- setupSurface(100, 100, new Rect(0, 10, 0, 10), 0, new Rect(0, 50, 100, 150));
- assertEquals(new Rect(0, 10, 100, 90), mSnapshotSurface.calculateSnapshotCrop());
+ final Rect contentInsets = new Rect(0, 10, 0, 10);
+ setupSurface(100, 100, contentInsets, 0, new Rect(0, 50, 100, 150));
+ assertEquals(new Rect(0, 10, 100, 90),
+ mSnapshotSurface.calculateSnapshotCrop(contentInsets));
}
@Test
public void testCalculateSnapshotCrop_navBarLeft() {
- setupSurface(100, 100, new Rect(10, 10, 0, 0), 0, new Rect(0, 0, 100, 100));
- assertEquals(new Rect(10, 0, 100, 100), mSnapshotSurface.calculateSnapshotCrop());
+ final Rect contentInsets = new Rect(0, 10, 0, 0);
+ setupSurface(100, 100, contentInsets, 0, new Rect(0, 0, 100, 100));
+ assertEquals(new Rect(10, 0, 100, 100),
+ mSnapshotSurface.calculateSnapshotCrop(contentInsets));
}
@Test
public void testCalculateSnapshotCrop_navBarRight() {
- setupSurface(100, 100, new Rect(0, 10, 10, 0), 0, new Rect(0, 0, 100, 100));
- assertEquals(new Rect(0, 0, 90, 100), mSnapshotSurface.calculateSnapshotCrop());
+ final Rect contentInsets = new Rect(0, 10, 10, 0);
+ setupSurface(100, 100, contentInsets, 0, new Rect(0, 0, 100, 100));
+ assertEquals(new Rect(0, 0, 90, 100),
+ mSnapshotSurface.calculateSnapshotCrop(contentInsets));
}
@Test
public void testCalculateSnapshotCrop_waterfall() {
- setupSurface(100, 100, new Rect(5, 10, 5, 10), 0, new Rect(0, 0, 100, 100));
- assertEquals(new Rect(5, 0, 95, 90), mSnapshotSurface.calculateSnapshotCrop());
+ final Rect contentInsets = new Rect(5, 10, 5, 10);
+ setupSurface(100, 100, contentInsets, 0, new Rect(0, 0, 100, 100));
+ assertEquals(new Rect(5, 0, 95, 90),
+ mSnapshotSurface.calculateSnapshotCrop(contentInsets));
}
@Test
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 8e772a2d1845..2ef2d3a968e0 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -16,12 +16,15 @@
package android.window;
+import static android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT;
+import static android.window.OnBackInvokedDispatcher.PRIORITY_OVERLAY;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
@@ -45,6 +48,9 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Tests for {@link WindowOnBackInvokedDispatcherTest}
*
@@ -69,6 +75,8 @@ public class WindowOnBackInvokedDispatcherTest {
@Mock
private ApplicationInfo mApplicationInfo;
+ private int mCallbackInfoCalls = 0;
+
private final BackMotionEvent mBackEvent = new BackMotionEvent(
/* touchX = */ 0,
/* touchY = */ 0,
@@ -93,105 +101,243 @@ public class WindowOnBackInvokedDispatcherTest {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
+ private List<OnBackInvokedCallbackInfo> captureCallbackInfo() throws RemoteException {
+ ArgumentCaptor<OnBackInvokedCallbackInfo> captor = ArgumentCaptor
+ .forClass(OnBackInvokedCallbackInfo.class);
+ // atLeast(0) -> get all setOnBackInvokedCallbackInfo() invocations
+ verify(mWindowSession, atLeast(0))
+ .setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), captor.capture());
+ verifyNoMoreInteractions(mWindowSession);
+ return captor.getAllValues();
+ }
+
+ private OnBackInvokedCallbackInfo assertSetCallbackInfo() throws RemoteException {
+ List<OnBackInvokedCallbackInfo> callbackInfos = captureCallbackInfo();
+ int actual = callbackInfos.size();
+ assertEquals("setOnBackInvokedCallbackInfo", ++mCallbackInfoCalls, actual);
+ return callbackInfos.get(mCallbackInfoCalls - 1);
+ }
+
+ private void assertNoSetCallbackInfo() throws RemoteException {
+ List<OnBackInvokedCallbackInfo> callbackInfos = captureCallbackInfo();
+ int actual = callbackInfos.size();
+ assertEquals("No setOnBackInvokedCallbackInfo", mCallbackInfoCalls, actual);
+ }
+
+ private void assertCallbacksSize(int expectedDefault, int expectedOverlay) {
+ ArrayList<OnBackInvokedCallback> callbacksDefault = mDispatcher
+ .mOnBackInvokedCallbacks.get(PRIORITY_DEFAULT);
+ int actualSizeDefault = callbacksDefault != null ? callbacksDefault.size() : 0;
+ assertEquals("mOnBackInvokedCallbacks DEFAULT size", expectedDefault, actualSizeDefault);
+
+ ArrayList<OnBackInvokedCallback> callbacksOverlay = mDispatcher
+ .mOnBackInvokedCallbacks.get(PRIORITY_OVERLAY);
+ int actualSizeOverlay = callbacksOverlay != null ? callbacksOverlay.size() : 0;
+ assertEquals("mOnBackInvokedCallbacks OVERLAY size", expectedOverlay, actualSizeOverlay);
+ }
+
+ private void assertTopCallback(OnBackInvokedCallback expectedCallback) {
+ assertEquals("topCallback", expectedCallback, mDispatcher.getTopCallback());
+ }
+
+ @Test
+ public void registerCallback_samePriority_sameCallback() throws RemoteException {
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ // The callback is removed and added again
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
+ }
+
+ @Test
+ public void registerCallback_samePriority_differentCallback() throws RemoteException {
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ // The new callback becomes the TopCallback
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ assertCallbacksSize(/* default */ 2, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback2);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
+ verifyNoMoreInteractions(mCallback2);
+ }
+
+ @Test
+ public void registerCallback_differentPriority_sameCallback() throws RemoteException {
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback1);
+ assertCallbacksSize(/* default */ 0, /* overlay */ 1);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ // The callback is moved to the new priority list
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
+ }
+
+ @Test
+ public void registerCallback_differentPriority_differentCallback() throws RemoteException {
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback1);
+ assertSetCallbackInfo();
+ assertCallbacksSize(/* default */ 0, /* overlay */ 1);
+ assertTopCallback(mCallback1);
+
+ // The callback with higher priority is still the TopCallback
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ assertNoSetCallbackInfo();
+ assertCallbacksSize(/* default */ 1, /* overlay */ 1);
+ assertTopCallback(mCallback1);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
+ verifyNoMoreInteractions(mCallback2);
+ }
+
+ @Test
+ public void registerCallback_sameInstanceAddedTwice() throws RemoteException {
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback1);
+ assertCallbacksSize(/* default */ 0, /* overlay */ 1);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 1);
+ assertNoSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertCallbacksSize(/* default */ 2, /* overlay */ 0);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback1);
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback2);
+ assertCallbacksSize(/* default */ 1, /* overlay */ 1);
+ assertSetCallbackInfo();
+ assertTopCallback(mCallback2);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
+ verifyNoMoreInteractions(mCallback2);
+ }
+
@Test
public void propagatesTopCallback_samePriority() throws RemoteException {
- ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
- ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
-
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
-
- verify(mWindowSession, times(2)).setOnBackInvokedCallbackInfo(
- Mockito.eq(mWindow),
- captor.capture());
- captor.getAllValues().get(0).getCallback().onBackStarted(mBackEvent);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ OnBackInvokedCallbackInfo callbackInfo1 = assertSetCallbackInfo();
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ OnBackInvokedCallbackInfo callbackInfo2 = assertSetCallbackInfo();
+
+ callbackInfo1.getCallback().onBackStarted(mBackEvent);
+
waitForIdle();
verify(mCallback1).onBackStarted(any(BackEvent.class));
verifyZeroInteractions(mCallback2);
- captor.getAllValues().get(1).getCallback().onBackStarted(mBackEvent);
+ callbackInfo2.getCallback().onBackStarted(mBackEvent);
+
waitForIdle();
verify(mCallback2).onBackStarted(any(BackEvent.class));
+
+ // Calls sequence: BackProgressAnimator.onBackStarted() -> BackProgressAnimator.reset() ->
+ // Spring.animateToFinalPosition(0). This causes a progress event to be fired.
+ verify(mCallback1, atMost(1)).onBackProgressed(any(BackEvent.class));
verifyNoMoreInteractions(mCallback1);
}
@Test
public void propagatesTopCallback_differentPriority() throws RemoteException {
- ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
- ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback1);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_OVERLAY, mCallback1);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
+ OnBackInvokedCallbackInfo callbackInfo = assertSetCallbackInfo();
- verify(mWindowSession).setOnBackInvokedCallbackInfo(
- Mockito.eq(mWindow), captor.capture());
verifyNoMoreInteractions(mWindowSession);
- assertEquals(captor.getValue().getPriority(), OnBackInvokedDispatcher.PRIORITY_OVERLAY);
- captor.getValue().getCallback().onBackStarted(mBackEvent);
+ assertEquals(callbackInfo.getPriority(), PRIORITY_OVERLAY);
+
+ callbackInfo.getCallback().onBackStarted(mBackEvent);
+
waitForIdle();
verify(mCallback1).onBackStarted(any(BackEvent.class));
}
@Test
public void propagatesTopCallback_withRemoval() throws RemoteException {
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertSetCallbackInfo();
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ assertSetCallbackInfo();
- reset(mWindowSession);
mDispatcher.unregisterOnBackInvokedCallback(mCallback1);
- verifyZeroInteractions(mWindowSession);
+
+ waitForIdle();
+ verifyNoMoreInteractions(mWindowSession);
+ verifyNoMoreInteractions(mCallback1);
mDispatcher.unregisterOnBackInvokedCallback(mCallback2);
+
+ waitForIdle();
verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), isNull());
}
@Test
public void propagatesTopCallback_sameInstanceAddedTwice() throws RemoteException {
- ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
- ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
-
- mDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_OVERLAY,
- mCallback1
- );
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
-
- reset(mWindowSession);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_OVERLAY, mCallback2);
- verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), captor.capture());
- captor.getValue().getCallback().onBackStarted(mBackEvent);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback1);
+ assertSetCallbackInfo();
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback2);
+ assertNoSetCallbackInfo();
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
+ assertSetCallbackInfo();
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_OVERLAY, mCallback2);
+
+ OnBackInvokedCallbackInfo lastCallbackInfo = assertSetCallbackInfo();
+
+ lastCallbackInfo.getCallback().onBackStarted(mBackEvent);
+
waitForIdle();
verify(mCallback2).onBackStarted(any(BackEvent.class));
}
@Test
public void onUnregisterWhileBackInProgress_callOnBackCancelled() throws RemoteException {
- ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
- ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
- mDispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
+ OnBackInvokedCallbackInfo callbackInfo = assertSetCallbackInfo();
+
+ callbackInfo.getCallback().onBackStarted(mBackEvent);
- verify(mWindowSession).setOnBackInvokedCallbackInfo(
- Mockito.eq(mWindow),
- captor.capture());
- IOnBackInvokedCallback iOnBackInvokedCallback = captor.getValue().getCallback();
- iOnBackInvokedCallback.onBackStarted(mBackEvent);
waitForIdle();
verify(mCallback1).onBackStarted(any(BackEvent.class));
mDispatcher.unregisterOnBackInvokedCallback(mCallback1);
+
+ waitForIdle();
verify(mCallback1).onBackCancelled();
- verifyNoMoreInteractions(mCallback1);
+ verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), isNull());
}
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 4b4e7220cb29..e4defcfa359f 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1135,6 +1135,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
+ "-1060529098": {
+ "message": " Skipping post-transition snapshot for task %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/Transition.java"
+ },
"-1060365734": {
"message": "Attempted to add QS dialog window with bad token %s. Aborting.",
"level": "WARN",
diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java
index f9113a21405c..6705b25ab0ec 100644
--- a/graphics/java/android/graphics/GraphicBuffer.java
+++ b/graphics/java/android/graphics/GraphicBuffer.java
@@ -57,7 +57,7 @@ public class GraphicBuffer implements Parcelable {
private final int mUsage;
// Note: do not rename, this field is used by native code
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private final long mNativeObject;
+ private long mNativeObject;
// These two fields are only used by lock/unlockCanvas()
private Canvas mCanvas;
@@ -219,6 +219,7 @@ public class GraphicBuffer implements Parcelable {
if (!mDestroyed) {
mDestroyed = true;
nDestroyGraphicBuffer(mNativeObject);
+ mNativeObject = 0;
}
}
@@ -239,7 +240,7 @@ public class GraphicBuffer implements Parcelable {
@Override
protected void finalize() throws Throwable {
try {
- if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
+ destroy();
} finally {
super.finalize();
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 89f4890c254e..4cedd41e2d9a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -308,7 +308,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
forAllTaskContainers(taskContainer -> {
synchronized (mLock) {
- final List<TaskFragmentContainer> containers = taskContainer.mContainers;
+ final List<TaskFragmentContainer> containers =
+ taskContainer.getTaskFragmentContainers();
// Clean up the TaskFragmentContainers by the z-order from the lowest.
for (int i = 0; i < containers.size(); i++) {
final TaskFragmentContainer container = containers.get(i);
@@ -611,8 +612,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@NonNull TaskContainer taskContainer) {
// Update all TaskFragments in the Task. Make a copy of the list since some may be
// removed on updating.
- final List<TaskFragmentContainer> containers =
- new ArrayList<>(taskContainer.mContainers);
+ final List<TaskFragmentContainer> containers = taskContainer.getTaskFragmentContainers();
for (int i = containers.size() - 1; i >= 0; i--) {
final TaskFragmentContainer container = containers.get(i);
// Wait until onTaskFragmentAppeared to update new container.
@@ -1331,7 +1331,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Check pending appeared activity first because there can be a delay for the server
// update.
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
- final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i)
+ .getTaskFragmentContainers();
for (int j = containers.size() - 1; j >= 0; j--) {
final TaskFragmentContainer container = containers.get(j);
if (container.hasPendingAppearedActivity(activityToken)) {
@@ -1342,7 +1343,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Check appeared activity if there is no such pending appeared activity.
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
- final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i)
+ .getTaskFragmentContainers();
for (int j = containers.size() - 1; j >= 0; j--) {
final TaskFragmentContainer container = containers.get(j);
if (container.hasAppearedActivity(activityToken)) {
@@ -1418,7 +1420,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) {
removeExistingSecondaryContainers(wct, primaryContainer);
}
- primaryContainer.getTaskContainer().mSplitContainers.add(splitContainer);
+ primaryContainer.getTaskContainer().addSplitContainer(splitContainer);
}
/** Cleanups all the dependencies when the TaskFragment is entering PIP. */
@@ -1430,8 +1432,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return;
}
final List<SplitContainer> splitsToRemove = new ArrayList<>();
+ final List<SplitContainer> splitContainers = taskContainer.getSplitContainers();
final Set<TaskFragmentContainer> containersToUpdate = new ArraySet<>();
- for (SplitContainer splitContainer : taskContainer.mSplitContainers) {
+ for (SplitContainer splitContainer : splitContainers) {
if (splitContainer.getPrimaryContainer() != container
&& splitContainer.getSecondaryContainer() != container) {
continue;
@@ -1449,7 +1452,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
}
container.resetDependencies();
- taskContainer.mSplitContainers.removeAll(splitsToRemove);
+ taskContainer.removeSplitContainers(splitsToRemove);
// If there is any TaskFragment split with the PIP TaskFragment, update their presentations
// since the split is dismissed.
// We don't want to close any of them even if they are dependencies of the PIP TaskFragment.
@@ -1471,7 +1474,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
void removeContainers(@NonNull TaskContainer taskContainer,
@NonNull List<TaskFragmentContainer> containers) {
// Remove all split containers that included this one
- taskContainer.mContainers.removeAll(containers);
+ taskContainer.removeTaskFragmentContainers(containers);
// Marked as a pending removal which will be removed after it is actually removed on the
// server side (#onTaskFragmentVanished).
// In this way, we can keep track of the Task bounds until we no longer have any
@@ -1481,7 +1484,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
// Cleanup any split references.
final List<SplitContainer> containersToRemove = new ArrayList<>();
- for (SplitContainer splitContainer : taskContainer.mSplitContainers) {
+ final List<SplitContainer> splitContainers = taskContainer.getSplitContainers();
+ for (SplitContainer splitContainer : splitContainers) {
if (containersToRemove.contains(splitContainer)) {
// Don't need to check because it has been in the remove list.
continue;
@@ -1492,10 +1496,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
containersToRemove.add(splitContainer);
}
}
- taskContainer.mSplitContainers.removeAll(containersToRemove);
+ taskContainer.removeSplitContainers(containersToRemove);
// Cleanup any dependent references.
- for (TaskFragmentContainer containerToUpdate : taskContainer.mContainers) {
+ final List<TaskFragmentContainer> taskFragmentContainers =
+ taskContainer.getTaskFragmentContainers();
+ for (TaskFragmentContainer containerToUpdate : taskFragmentContainers) {
containerToUpdate.removeContainersToFinishOnExit(containers);
}
}
@@ -1534,8 +1540,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (taskContainer == null) {
return null;
}
- for (int i = taskContainer.mContainers.size() - 1; i >= 0; i--) {
- final TaskFragmentContainer container = taskContainer.mContainers.get(i);
+ final List<TaskFragmentContainer> containers = taskContainer.getTaskFragmentContainers();
+ for (int i = containers.size() - 1; i >= 0; i--) {
+ final TaskFragmentContainer container = containers.get(i);
if (!container.isFinished() && (container.getRunningActivityCount() > 0
// We may be waiting for the top TaskFragment to become non-empty after
// creation. In that case, we don't want to treat the TaskFragment below it as
@@ -1629,7 +1636,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
/** Whether the given split is the topmost split in the Task. */
private boolean isTopMostSplit(@NonNull SplitContainer splitContainer) {
final List<SplitContainer> splitContainers = splitContainer.getPrimaryContainer()
- .getTaskContainer().mSplitContainers;
+ .getTaskContainer().getSplitContainers();
return splitContainer == splitContainers.get(splitContainers.size() - 1);
}
@@ -1641,7 +1648,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
if (container == null) {
return null;
}
- final List<SplitContainer> splitContainers = container.getTaskContainer().mSplitContainers;
+ final List<SplitContainer> splitContainers =
+ container.getTaskContainer().getSplitContainers();
if (splitContainers.isEmpty()) {
return null;
}
@@ -1665,7 +1673,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@NonNull TaskFragmentContainer firstContainer,
@NonNull TaskFragmentContainer secondContainer) {
final List<SplitContainer> splitContainers = firstContainer.getTaskContainer()
- .mSplitContainers;
+ .getSplitContainers();
for (int i = splitContainers.size() - 1; i >= 0; i--) {
final SplitContainer splitContainer = splitContainers.get(i);
final TaskFragmentContainer primary = splitContainer.getPrimaryContainer();
@@ -1930,7 +1938,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@GuardedBy("mLock")
TaskFragmentContainer getContainer(@NonNull IBinder fragmentToken) {
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
- final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
+ final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i)
+ .getTaskFragmentContainers();
for (TaskFragmentContainer container : containers) {
if (container.getTaskFragmentToken().equals(fragmentToken)) {
return container;
@@ -1945,7 +1954,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
@GuardedBy("mLock")
SplitContainer getSplitContainer(@NonNull IBinder token) {
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
- final List<SplitContainer> containers = mTaskContainers.valueAt(i).mSplitContainers;
+ final List<SplitContainer> containers = mTaskContainers.valueAt(i).getSplitContainers();
for (SplitContainer container : containers) {
if (container.getToken().equals(token)) {
return container;
@@ -2091,7 +2100,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
}
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i)
- .mContainers;
+ .getTaskFragmentContainers();
for (int j = containers.size() - 1; j >= 0; j--) {
final TaskFragmentContainer container = containers.get(j);
if (!container.hasActivity(activityToken)
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index 4b15bb187035..4580c9836168 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -51,11 +51,11 @@ class TaskContainer {
/** Active TaskFragments in this Task. */
@NonNull
- final List<TaskFragmentContainer> mContainers = new ArrayList<>();
+ private final List<TaskFragmentContainer> mContainers = new ArrayList<>();
/** Active split pairs in this Task. */
@NonNull
- final List<SplitContainer> mSplitContainers = new ArrayList<>();
+ private final List<SplitContainer> mSplitContainers = new ArrayList<>();
@NonNull
private final Configuration mConfiguration;
@@ -207,6 +207,53 @@ class TaskContainer {
return false;
}
+ /**
+ * Returns a list of {@link SplitContainer}. Do not modify the containers directly on the
+ * returned list. Use {@link #addSplitContainer} or {@link #removeSplitContainers} instead.
+ */
+ @NonNull
+ List<SplitContainer> getSplitContainers() {
+ return mSplitContainers;
+ }
+
+ void addSplitContainer(@NonNull SplitContainer splitContainer) {
+ mSplitContainers.add(splitContainer);
+ }
+
+ void removeSplitContainers(@NonNull List<SplitContainer> containers) {
+ mSplitContainers.removeAll(containers);
+ }
+
+ void addTaskFragmentContainer(@NonNull TaskFragmentContainer taskFragmentContainer) {
+ mContainers.add(taskFragmentContainer);
+ }
+
+ void addTaskFragmentContainer(int index, @NonNull TaskFragmentContainer taskFragmentContainer) {
+ mContainers.add(index, taskFragmentContainer);
+ }
+
+ void removeTaskFragmentContainer(@NonNull TaskFragmentContainer taskFragmentContainer) {
+ mContainers.remove(taskFragmentContainer);
+ }
+
+ void removeTaskFragmentContainers(@NonNull List<TaskFragmentContainer> taskFragmentContainer) {
+ mContainers.removeAll(taskFragmentContainer);
+ }
+
+ void clearTaskFragmentContainer() {
+ mContainers.clear();
+ }
+
+ /**
+ * Returns a list of {@link TaskFragmentContainer}. Do not modify the containers directly on
+ * the returned list. Use {@link #addTaskFragmentContainer},
+ * {@link #removeTaskFragmentContainer} or other related methods instead.
+ */
+ @NonNull
+ List<TaskFragmentContainer> getTaskFragmentContainers() {
+ return mContainers;
+ }
+
/** Adds the descriptors of split states in this Task to {@code outSplitStates}. */
void getSplitStates(@NonNull List<SplitInfo> outSplitStates) {
for (SplitContainer container : mSplitContainers) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 60be9d16d749..61df335515b8 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -180,23 +180,25 @@ class TaskFragmentContainer {
throw new IllegalArgumentException(
"pairedPrimaryContainer must be in the same Task");
}
- final int primaryIndex = taskContainer.mContainers.indexOf(pairedPrimaryContainer);
- taskContainer.mContainers.add(primaryIndex + 1, this);
+ final int primaryIndex = taskContainer.indexOf(pairedPrimaryContainer);
+ taskContainer.addTaskFragmentContainer(primaryIndex + 1, this);
} else if (pendingAppearedActivity != null) {
// The TaskFragment will be positioned right above the pending appeared Activity. If any
// existing TaskFragment is empty with pending Intent, it is likely that the Activity of
// the pending Intent hasn't been created yet, so the new Activity should be below the
// empty TaskFragment.
- int i = taskContainer.mContainers.size() - 1;
+ final List<TaskFragmentContainer> containers =
+ taskContainer.getTaskFragmentContainers();
+ int i = containers.size() - 1;
for (; i >= 0; i--) {
- final TaskFragmentContainer container = taskContainer.mContainers.get(i);
+ final TaskFragmentContainer container = containers.get(i);
if (!container.isEmpty() || container.getPendingAppearedIntent() == null) {
break;
}
}
- taskContainer.mContainers.add(i + 1, this);
+ taskContainer.addTaskFragmentContainer(i + 1, this);
} else {
- taskContainer.mContainers.add(this);
+ taskContainer.addTaskFragmentContainer(this);
}
if (pendingAppearedActivity != null) {
addPendingAppearedActivity(pendingAppearedActivity);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index ff08782e8cd8..9e264726a65a 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -183,23 +183,23 @@ public class SplitControllerTest {
// tf2 has running activity so is active.
final TaskFragmentContainer tf2 = mock(TaskFragmentContainer.class);
doReturn(1).when(tf2).getRunningActivityCount();
- taskContainer.mContainers.add(tf2);
+ taskContainer.addTaskFragmentContainer(tf2);
// tf3 is finished so is not active.
final TaskFragmentContainer tf3 = mock(TaskFragmentContainer.class);
doReturn(true).when(tf3).isFinished();
doReturn(false).when(tf3).isWaitingActivityAppear();
- taskContainer.mContainers.add(tf3);
+ taskContainer.addTaskFragmentContainer(tf3);
mSplitController.mTaskContainers.put(TASK_ID, taskContainer);
assertWithMessage("Must return tf2 because tf3 is not active.")
.that(mSplitController.getTopActiveContainer(TASK_ID)).isEqualTo(tf2);
- taskContainer.mContainers.remove(tf3);
+ taskContainer.removeTaskFragmentContainer(tf3);
assertWithMessage("Must return tf2 because tf2 has running activity.")
.that(mSplitController.getTopActiveContainer(TASK_ID)).isEqualTo(tf2);
- taskContainer.mContainers.remove(tf2);
+ taskContainer.removeTaskFragmentContainer(tf2);
assertWithMessage("Must return tf because we are waiting for tf1 to appear.")
.that(mSplitController.getTopActiveContainer(TASK_ID)).isEqualTo(tf1);
@@ -320,11 +320,11 @@ public class SplitControllerTest {
doReturn(tf).when(splitContainer).getSecondaryContainer();
doReturn(createTestTaskContainer()).when(splitContainer).getTaskContainer();
doReturn(createSplitRule(mActivity, mActivity)).when(splitContainer).getSplitRule();
- final List<SplitContainer> splitContainers =
- mSplitController.getTaskContainer(TASK_ID).mSplitContainers;
- splitContainers.add(splitContainer);
+ final TaskContainer taskContainer = mSplitController.getTaskContainer(TASK_ID);
+ taskContainer.addSplitContainer(splitContainer);
// Add a mock SplitContainer on top of splitContainer
- splitContainers.add(1, mock(SplitContainer.class));
+ final SplitContainer splitContainer2 = mock(SplitContainer.class);
+ taskContainer.addSplitContainer(splitContainer2);
mSplitController.updateContainer(mTransaction, tf);
@@ -332,7 +332,9 @@ public class SplitControllerTest {
// Verify if one or both containers in the top SplitContainer are finished,
// dismissPlaceholder() won't be called.
- splitContainers.remove(1);
+ final ArrayList<SplitContainer> splitContainersToRemove = new ArrayList<>();
+ splitContainersToRemove.add(splitContainer2);
+ taskContainer.removeSplitContainers(splitContainersToRemove);
doReturn(true).when(tf).isFinished();
mSplitController.updateContainer(mTransaction, tf);
@@ -363,7 +365,8 @@ public class SplitControllerTest {
final Activity r1 = createMockActivity();
addSplitTaskFragments(r0, r1);
final TaskContainer taskContainer = mSplitController.getTaskContainer(TASK_ID);
- final TaskFragmentContainer taskFragmentContainer = taskContainer.mContainers.get(0);
+ final TaskFragmentContainer taskFragmentContainer =
+ taskContainer.getTaskFragmentContainers().get(0);
spyOn(taskContainer);
// No update when the Task is invisible.
@@ -377,7 +380,7 @@ public class SplitControllerTest {
doReturn(true).when(taskContainer).isVisible();
mSplitController.updateContainer(mTransaction, taskFragmentContainer);
- verify(mSplitPresenter).updateSplitContainer(taskContainer.mSplitContainers.get(0),
+ verify(mSplitPresenter).updateSplitContainer(taskContainer.getSplitContainers().get(0),
mTransaction);
}
@@ -1090,8 +1093,8 @@ public class SplitControllerTest {
verify(mTransaction).finishActivity(mActivity.getActivityToken());
verify(mTransaction).finishActivity(secondaryActivity0.getActivityToken());
verify(mTransaction).finishActivity(secondaryActivity1.getActivityToken());
- assertTrue(taskContainer.mContainers.isEmpty());
- assertTrue(taskContainer.mSplitContainers.isEmpty());
+ assertTrue(taskContainer.getTaskFragmentContainers().isEmpty());
+ assertTrue(taskContainer.getSplitContainers().isEmpty());
}
@Test
@@ -1363,15 +1366,13 @@ public class SplitControllerTest {
TaskFragmentContainer tf = mSplitController.newContainer(mActivity, TASK_ID);
tf.setInfo(mTransaction, createMockTaskFragmentInfo(tf, mActivity));
- List<TaskFragmentContainer> containers = mSplitController.mTaskContainers.get(TASK_ID)
- .mContainers;
-
- assertEquals(containers.get(0), tf);
+ final TaskContainer taskContainer = mSplitController.mTaskContainers.get(TASK_ID);
+ assertEquals(taskContainer.getTaskFragmentContainers().get(0), tf);
mSplitController.finishActivityStacks(Collections.singleton(tf.getTaskFragmentToken()));
verify(mSplitPresenter).deleteTaskFragment(any(), eq(tf.getTaskFragmentToken()));
- assertTrue(containers.isEmpty());
+ assertTrue(taskContainer.getTaskFragmentContainers().isEmpty());
}
@Test
@@ -1381,10 +1382,8 @@ public class SplitControllerTest {
bottomTf.setInfo(mTransaction, createMockTaskFragmentInfo(bottomTf, mActivity));
topTf.setInfo(mTransaction, createMockTaskFragmentInfo(topTf, createMockActivity()));
- List<TaskFragmentContainer> containers = mSplitController.mTaskContainers.get(TASK_ID)
- .mContainers;
-
- assertEquals(containers.size(), 2);
+ final TaskContainer taskContainer = mSplitController.mTaskContainers.get(TASK_ID);
+ assertEquals(taskContainer.getTaskFragmentContainers().size(), 2);
Set<IBinder> activityStackTokens = new ArraySet<>(new IBinder[]{
topTf.getTaskFragmentToken(), bottomTf.getTaskFragmentToken()});
@@ -1403,7 +1402,7 @@ public class SplitControllerTest {
+ "regardless of the order in ActivityStack set",
topTf.getTaskFragmentToken(), fragmentTokens.get(1));
- assertTrue(containers.isEmpty());
+ assertTrue(taskContainer.getTaskFragmentContainers().isEmpty());
}
@Test
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
index 13e709271221..11af1d1f20e1 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
@@ -127,7 +127,7 @@ public class TaskContainerTest {
assertFalse(taskContainer.isEmpty());
taskContainer.mFinishedContainer.add(tf.getTaskFragmentToken());
- taskContainer.mContainers.clear();
+ taskContainer.clearTaskFragmentContainer();
assertFalse(taskContainer.isEmpty());
}
@@ -152,13 +152,13 @@ public class TaskContainerTest {
assertNull(taskContainer.getTopNonFinishingActivity());
final TaskFragmentContainer tf0 = mock(TaskFragmentContainer.class);
- taskContainer.mContainers.add(tf0);
+ taskContainer.addTaskFragmentContainer(tf0);
final Activity activity0 = mock(Activity.class);
doReturn(activity0).when(tf0).getTopNonFinishingActivity();
assertEquals(activity0, taskContainer.getTopNonFinishingActivity());
final TaskFragmentContainer tf1 = mock(TaskFragmentContainer.class);
- taskContainer.mContainers.add(tf1);
+ taskContainer.addTaskFragmentContainer(tf1);
assertEquals(activity0, taskContainer.getTopNonFinishingActivity());
final Activity activity1 = mock(Activity.class);
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_section.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_section.xml
new file mode 100644
index 000000000000..d99d64d8da20
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_section.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <ripple android:color="#99999999">
+ <item android:drawable="@drawable/bubble_manage_menu_bg" />
+ </ripple>
+ </item>
+ <item android:drawable="@drawable/bubble_manage_menu_bg" />
+</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/ic_expand_less.xml b/libs/WindowManager/Shell/res/drawable/ic_expand_less.xml
new file mode 100644
index 000000000000..f4508464883d
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_expand_less.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M18.59,16.41L20,15L12,7L4,15L5.41,16.41L12,9.83"
+ android:fillColor="#5F6368"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
new file mode 100644
index 000000000000..ddcd5c60d9c8
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<com.android.wm.shell.bubbles.bar.BubbleBarMenuItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/bubble_bar_manage_menu_item_height"
+ android:gravity="center_vertical"
+ android:paddingStart="@dimen/bubble_menu_padding"
+ android:paddingEnd="@dimen/bubble_menu_padding"
+ android:background="@drawable/bubble_manage_menu_row">
+
+ <ImageView
+ android:id="@+id/bubble_bar_menu_item_icon"
+ android:layout_width="@dimen/bubble_bar_manage_menu_item_icon_size"
+ android:layout_height="@dimen/bubble_bar_manage_menu_item_icon_size"
+ android:contentDescription="@null"/>
+
+ <TextView
+ android:id="@+id/bubble_bar_menu_item_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
+
+</com.android.wm.shell.bubbles.bar.BubbleBarMenuItemView> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
new file mode 100644
index 000000000000..82e5aee41ff2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<com.android.wm.shell.bubbles.bar.BubbleBarMenuView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:minWidth="@dimen/bubble_bar_manage_menu_min_width"
+ android:orientation="vertical"
+ android:elevation="@dimen/bubble_manage_menu_elevation"
+ android:paddingTop="@dimen/bubble_bar_manage_menu_padding_top"
+ android:paddingHorizontal="@dimen/bubble_bar_manage_menu_padding"
+ android:paddingBottom="@dimen/bubble_bar_manage_menu_padding"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:id="@+id/bubble_bar_manage_menu_bubble_section"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/bubble_bar_manage_menu_item_height"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:paddingStart="14dp"
+ android:paddingEnd="12dp"
+ android:background="@drawable/bubble_manage_menu_section"
+ android:elevation="@dimen/bubble_manage_menu_elevation">
+
+ <ImageView
+ android:id="@+id/bubble_bar_manage_menu_bubble_icon"
+ android:layout_width="@dimen/bubble_menu_icon_size"
+ android:layout_height="@dimen/bubble_menu_icon_size"
+ android:contentDescription="@null" />
+
+ <TextView
+ android:id="@+id/bubble_bar_manage_menu_bubble_title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:layout_weight="1"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
+
+ <ImageView
+ android:id="@+id/bubble_bar_manage_menu_dismiss_icon"
+ android:layout_width="@dimen/bubble_bar_manage_menu_dismiss_icon_size"
+ android:layout_height="@dimen/bubble_bar_manage_menu_dismiss_icon_size"
+ android:layout_marginStart="8dp"
+ android:contentDescription="@null"
+ android:src="@drawable/ic_expand_less"
+ app:tint="?android:attr/textColorPrimary" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/bubble_bar_manage_menu_actions_section"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="@dimen/bubble_bar_manage_menu_section_spacing"
+ android:background="@drawable/bubble_manage_menu_bg"
+ android:elevation="@dimen/bubble_manage_menu_elevation" />
+
+</com.android.wm.shell.bubbles.bar.BubbleBarMenuView> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 9434d48286b9..8f2f6d8e882f 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -54,7 +54,7 @@
<string name="accessibility_split_top" msgid="2789329702027147146">"上に分割"</string>
<string name="accessibility_split_bottom" msgid="8694551025220868191">"下に分割"</string>
<string name="one_handed_tutorial_title" msgid="4583241688067426350">"片手モードの使用"</string>
- <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの任意の場所をタップします"</string>
+ <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの上側の任意の場所をタップします"</string>
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"片手モードを開始します"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"片手モードを終了します"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"<xliff:g id="APP_NAME">%1$s</xliff:g> のバブルの設定"</string>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 6f8a7666e5a8..f2a07857cd4a 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -32,6 +32,7 @@
<color name="bubbles_icon_tint">@color/GM2_grey_700</color>
<color name="bubble_bar_expanded_view_handle_light">#EBffffff</color>
<color name="bubble_bar_expanded_view_handle_dark">#99000000</color>
+ <color name="bubble_bar_expanded_view_menu_close">#DC362E</color>
<!-- PiP -->
<color name="pip_custom_close_bg">#D93025</color>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index aa05179ed113..214125928892 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -234,6 +234,20 @@
<dimen name="bubble_bar_expanded_view_handle_width">128dp</dimen>
<!-- The height of the drag handle shown along with a bubble bar expanded view. -->
<dimen name="bubble_bar_expanded_view_handle_height">4dp</dimen>
+ <!-- Minimum width of the bubble bar manage menu. -->
+ <dimen name="bubble_bar_manage_menu_min_width">200dp</dimen>
+ <!-- Size of the dismiss icon in the bubble bar manage menu. -->
+ <dimen name="bubble_bar_manage_menu_dismiss_icon_size">16dp</dimen>
+ <!-- Padding of the bubble bar manage menu, provides space for menu shadows -->
+ <dimen name="bubble_bar_manage_menu_padding">8dp</dimen>
+ <!-- Top padding of the bubble bar manage menu -->
+ <dimen name="bubble_bar_manage_menu_padding_top">2dp</dimen>
+ <!-- Spacing between sections of the bubble bar manage menu -->
+ <dimen name="bubble_bar_manage_menu_section_spacing">2dp</dimen>
+ <!-- Height of an item in the bubble bar manage menu. -->
+ <dimen name="bubble_bar_manage_menu_item_height">52dp</dimen>
+ <!-- Size of the icons in the bubble bar manage menu. -->
+ <dimen name="bubble_bar_manage_menu_item_icon_size">20dp</dimen>
<!-- Bottom and end margin for compat buttons. -->
<dimen name="compat_button_margin">24dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING
deleted file mode 100644
index 8dd1369ecbb2..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "ironwood-postsubmit": [
- {
- "name": "WMShellFlickerTests",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
- ]
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 102f2cb4b8d0..504839fedf06 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -855,7 +855,8 @@ public class Bubble implements BubbleViewProvider {
return mIsAppBubble;
}
- Intent getSettingsIntent(final Context context) {
+ /** Creates open app settings intent */
+ public Intent getSettingsIntent(final Context context) {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
final int uid = getUid(context);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 3eb9fa2eef6b..39338e5baddb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -720,6 +720,7 @@ public class BubbleController implements ConfigurationChangeListener,
// TODO(b/273312602): consider foldables where we do need a stack view when folded
if (mLayerView == null) {
mLayerView = new BubbleBarLayerView(mContext, this);
+ mLayerView.setUnBubbleConversationCallback(mSysuiProxy::onUnbubbleConversation);
}
} else {
if (mStackView == null) {
@@ -1221,6 +1222,13 @@ public class BubbleController implements ConfigurationChangeListener,
}
/**
+ * Dismiss bubble if it exists and remove it from the stack
+ */
+ public void dismissBubble(Bubble bubble, @Bubbles.DismissReason int reason) {
+ mBubbleData.dismissBubbleWithKey(bubble.getKey(), reason);
+ }
+
+ /**
* Performs a screenshot that may exclude the bubble layer, if one is present. The screenshot
* can be access via the supplied {@link ScreenshotSync#get()} asynchronously.
*/
@@ -1846,7 +1854,7 @@ public class BubbleController implements ConfigurationChangeListener,
if (mStackView != null) {
mStackView.setVisibility(VISIBLE);
}
- if (mLayerView != null && isStackExpanded()) {
+ if (mLayerView != null) {
mLayerView.setVisibility(VISIBLE);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 91c7cc0c6e89..68fea41e134e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2518,6 +2518,7 @@ public class BubbleStackView extends FrameLayout
mExpandedAnimationController.expandFromStack(() -> {
updatePointerPosition(false /* forIme */);
afterExpandedViewAnimation();
+ mExpandedViewContainer.setVisibility(VISIBLE);
mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
} /* after */);
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
index 7a5815994dd0..da4a9898a44c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.bubbles;
+import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
@@ -110,6 +111,9 @@ public class BubbleTaskViewHelper {
try {
options.setTaskAlwaysOnTop(true);
options.setLaunchedFromBubble(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ options.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true);
Intent fillInIntent = new Intent();
// Apply flags to make behaviour match documentLaunchMode=always.
@@ -117,11 +121,19 @@ public class BubbleTaskViewHelper {
fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
if (mBubble.isAppBubble()) {
- PendingIntent pi = PendingIntent.getActivity(mContext, 0,
- mBubble.getAppBubbleIntent(),
- PendingIntent.FLAG_MUTABLE,
- null);
- mTaskView.startActivity(pi, fillInIntent, options, launchBounds);
+ Context context =
+ mContext.createContextAsUser(
+ mBubble.getUser(), Context.CONTEXT_RESTRICTED);
+ PendingIntent pi = PendingIntent.getActivity(
+ context,
+ /* requestCode= */ 0,
+ mBubble.getAppBubbleIntent()
+ .addFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
+ .addFlags(FLAG_ACTIVITY_MULTIPLE_TASK),
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
+ /* options= */ null);
+ mTaskView.startActivity(pi, /* fillInIntent= */ null, options,
+ launchBounds);
} else if (mBubble.hasMetadataShortcutId()) {
options.setApplyActivityFlagsForBubbles(true);
mTaskView.startShortcutActivity(mBubble.getShortcutInfo(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index 8ab9841ff0c2..3a46797d4a3d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -192,6 +192,11 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
}
info.rawBadgeBitmap = iconFactory.getBadgeBitmap(badgedIcon, false).icon;
+ float[] bubbleBitmapScale = new float[1];
+ info.bubbleBitmap = iconFactory.getBubbleBitmap(
+ iconFactory.getBubbleDrawable(c, info.shortcutInfo,
+ b.getIcon()), bubbleBitmapScale);
+
return info;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index da1a5572e53b..32ed10258eee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -33,8 +34,12 @@ import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubble;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.bubbles.BubbleTaskViewHelper;
+import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.taskview.TaskView;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
/**
* Expanded view of a bubble when it's part of the bubble bar.
*
@@ -47,6 +52,9 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
private BubbleController mController;
private BubbleTaskViewHelper mBubbleTaskViewHelper;
+ private BubbleBarMenuViewController mMenuViewController;
+ private @Nullable Supplier<Rect> mLayerBoundsSupplier;
+ private @Nullable Consumer<String> mUnBubbleConversationCallback;
private BubbleBarHandleView mHandleView = new BubbleBarHandleView(getContext());
private @Nullable TaskView mTaskView;
@@ -98,6 +106,13 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
});
}
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ // Hide manage menu when view disappears
+ mMenuViewController.hideMenu(false /* animated */);
+ }
+
/** Set the BubbleController on the view, must be called before doing anything else. */
public void initialize(BubbleController controller) {
mController = controller;
@@ -108,6 +123,36 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
addView(mTaskView);
mTaskView.setEnableSurfaceClipping(true);
mTaskView.setCornerRadius(mCornerRadius);
+ mMenuViewController = new BubbleBarMenuViewController(mContext, this);
+ mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
+ @Override
+ public void onMenuVisibilityChanged(boolean visible) {
+ if (mTaskView == null || mLayerBoundsSupplier == null) return;
+ // Updates the obscured touchable region for the task surface.
+ mTaskView.setObscuredTouchRect(visible ? mLayerBoundsSupplier.get() : null);
+ }
+
+ @Override
+ public void onUnBubbleConversation(Bubble bubble) {
+ if (mUnBubbleConversationCallback != null) {
+ mUnBubbleConversationCallback.accept(bubble.getKey());
+ }
+ }
+
+ @Override
+ public void onOpenAppSettings(Bubble bubble) {
+ mController.collapseStack();
+ mContext.startActivityAsUser(bubble.getSettingsIntent(mContext), bubble.getUser());
+ }
+
+ @Override
+ public void onDismissBubble(Bubble bubble) {
+ mController.dismissBubble(bubble, Bubbles.DISMISS_USER_REMOVED);
+ }
+ });
+ mHandleView.setOnClickListener(view -> {
+ mMenuViewController.showMenu(true /* animated */);
+ });
}
// TODO (b/275087636): call this when theme/config changes
@@ -183,11 +228,13 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
}
mBubbleTaskViewHelper.cleanUpTaskView();
}
+ mMenuViewController.hideMenu(false /* animated */);
}
- /** Updates the bubble shown in this task view. */
+ /** Updates the bubble shown in the expanded view. */
public void update(Bubble bubble) {
mBubbleTaskViewHelper.update(bubble);
+ mMenuViewController.updateMenu(bubble);
}
/** The task id of the activity shown in the task view, if it exists. */
@@ -195,6 +242,17 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
return mBubbleTaskViewHelper != null ? mBubbleTaskViewHelper.getTaskId() : INVALID_TASK_ID;
}
+ /** Sets layer bounds supplier used for obscured touchable region of task view */
+ void setLayerBoundsSupplier(@Nullable Supplier<Rect> supplier) {
+ mLayerBoundsSupplier = supplier;
+ }
+
+ /** Sets the function to call to un-bubble the given conversation. */
+ public void setUnBubbleConversationCallback(
+ @Nullable Consumer<String> unBubbleConversationCallback) {
+ mUnBubbleConversationCallback = unBubbleConversationCallback;
+ }
+
/**
* Call when the location or size of the view has changed to update TaskView.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
index e121aa45469d..ce26bc0322b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -20,7 +20,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -38,35 +37,35 @@ import com.android.wm.shell.R;
public class BubbleBarHandleView extends View {
private static final long COLOR_CHANGE_DURATION = 120;
- private final int mHandleWidth;
- private final int mHandleHeight;
- private final @ColorInt int mHandleLightColor;
- private final @ColorInt int mHandleDarkColor;
+ private int mHandleWidth;
+ private int mHandleHeight;
+ private @ColorInt int mHandleLightColor;
+ private @ColorInt int mHandleDarkColor;
private @Nullable ObjectAnimator mColorChangeAnim;
public BubbleBarHandleView(Context context) {
- this(context, null);
+ this(context, null /* attrs */);
}
public BubbleBarHandleView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, 0 /* defStyleAttr */);
}
public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
+ this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
}
public BubbleBarHandleView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- Resources resources = context.getResources();
- mHandleWidth = resources.getDimensionPixelSize(
+
+ mHandleWidth = getResources().getDimensionPixelSize(
R.dimen.bubble_bar_expanded_view_handle_width);
- mHandleHeight = resources.getDimensionPixelSize(
+ mHandleHeight = getResources().getDimensionPixelSize(
R.dimen.bubble_bar_expanded_view_handle_height);
- mHandleLightColor = ContextCompat.getColor(context,
+ mHandleLightColor = ContextCompat.getColor(getContext(),
R.color.bubble_bar_expanded_view_handle_light);
- mHandleDarkColor = ContextCompat.getColor(context,
+ mHandleDarkColor = ContextCompat.getColor(getContext(),
R.color.bubble_bar_expanded_view_handle_dark);
setClipToOutline(true);
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 b1a725b6e5c4..bc622e7a7a3e 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
@@ -32,6 +32,8 @@ import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleViewProvider;
+import java.util.function.Consumer;
+
/**
* Similar to {@link com.android.wm.shell.bubbles.BubbleStackView}, this view is added to window
* manager to display bubbles. However, it is only used when bubbles are being displayed in
@@ -53,6 +55,7 @@ public class BubbleBarLayerView extends FrameLayout
@Nullable
private BubbleViewProvider mExpandedBubble;
private BubbleBarExpandedView mExpandedView;
+ private @Nullable Consumer<String> mUnBubbleConversationCallback;
// TODO(b/273310265) - currently the view is always on the right, need to update for RTL.
/** Whether the expanded view is displaying on the left of the screen or not. */
@@ -146,6 +149,13 @@ public class BubbleBarLayerView extends FrameLayout
final int width = mPositioner.getExpandedViewWidthForBubbleBar();
final int height = mPositioner.getExpandedViewHeightForBubbleBar();
mExpandedView.setVisibility(GONE);
+ mExpandedView.setUnBubbleConversationCallback(mUnBubbleConversationCallback);
+ mExpandedView.setLayerBoundsSupplier(() -> new Rect(0, 0, getWidth(), getHeight()));
+ mExpandedView.setUnBubbleConversationCallback(bubbleKey -> {
+ if (mUnBubbleConversationCallback != null) {
+ mUnBubbleConversationCallback.accept(bubbleKey);
+ }
+ });
addView(mExpandedView, new FrameLayout.LayoutParams(width, height));
}
@@ -165,6 +175,12 @@ public class BubbleBarLayerView extends FrameLayout
showScrim(false);
}
+ /** Sets the function to call to un-bubble the given conversation. */
+ public void setUnBubbleConversationCallback(
+ @Nullable Consumer<String> unBubbleConversationCallback) {
+ mUnBubbleConversationCallback = unBubbleConversationCallback;
+ }
+
/** Updates the expanded view size and position. */
private void updateExpandedView() {
if (mExpandedView == null) return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
new file mode 100644
index 000000000000..00b977721bea
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar;
+
+import android.annotation.ColorInt;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Bubble bar expanded view menu item view to display menu action details
+ */
+public class BubbleBarMenuItemView extends LinearLayout {
+ private ImageView mImageView;
+ private TextView mTextView;
+
+ public BubbleBarMenuItemView(Context context) {
+ this(context, null /* attrs */);
+ }
+
+ public BubbleBarMenuItemView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0 /* defStyleAttr */);
+ }
+
+ public BubbleBarMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
+ }
+
+ public BubbleBarMenuItemView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mImageView = findViewById(R.id.bubble_bar_menu_item_icon);
+ mTextView = findViewById(R.id.bubble_bar_menu_item_title);
+ }
+
+ /**
+ * Update menu item with the details and tint color
+ */
+ void update(Icon icon, String title, @ColorInt int tint) {
+ if (tint == Color.TRANSPARENT) {
+ final TypedArray typedArray = getContext().obtainStyledAttributes(
+ new int[]{android.R.attr.textColorPrimary});
+ mTextView.setTextColor(typedArray.getColor(0, Color.BLACK));
+ } else {
+ icon.setTint(tint);
+ mTextView.setTextColor(tint);
+ }
+
+ mImageView.setImageIcon(icon);
+ mTextView.setText(title);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
new file mode 100644
index 000000000000..211fe0d48e43
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar;
+
+import android.annotation.ColorInt;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.Bubble;
+
+import java.util.ArrayList;
+
+/**
+ * Bubble bar expanded view menu
+ */
+public class BubbleBarMenuView extends LinearLayout {
+ private ViewGroup mBubbleSectionView;
+ private ViewGroup mActionsSectionView;
+ private ImageView mBubbleIconView;
+ private TextView mBubbleTitleView;
+
+ public BubbleBarMenuView(Context context) {
+ this(context, null /* attrs */);
+ }
+
+ public BubbleBarMenuView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0 /* defStyleAttr */);
+ }
+
+ public BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0 /* defStyleRes */);
+ }
+
+ public BubbleBarMenuView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mBubbleSectionView = findViewById(R.id.bubble_bar_manage_menu_bubble_section);
+ mActionsSectionView = findViewById(R.id.bubble_bar_manage_menu_actions_section);
+ mBubbleIconView = findViewById(R.id.bubble_bar_manage_menu_bubble_icon);
+ mBubbleTitleView = findViewById(R.id.bubble_bar_manage_menu_bubble_title);
+ }
+
+ /** Update menu details with bubble info */
+ void updateInfo(Bubble bubble) {
+ if (bubble.getIcon() != null) {
+ mBubbleIconView.setImageIcon(bubble.getIcon());
+ } else {
+ mBubbleIconView.setImageBitmap(bubble.getBubbleIcon());
+ }
+ mBubbleTitleView.setText(bubble.getTitle());
+ }
+
+ /**
+ * Update menu action items views
+ * @param actions used to populate menu item views
+ */
+ void updateActions(ArrayList<MenuAction> actions) {
+ mActionsSectionView.removeAllViews();
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+
+ for (MenuAction action : actions) {
+ BubbleBarMenuItemView itemView = (BubbleBarMenuItemView) inflater.inflate(
+ R.layout.bubble_bar_menu_item, mActionsSectionView, false);
+ itemView.update(action.mIcon, action.mTitle, action.mTint);
+ itemView.setOnClickListener(action.mOnClick);
+ mActionsSectionView.addView(itemView);
+ }
+ }
+
+ /** Sets on close menu listener */
+ void setOnCloseListener(Runnable onClose) {
+ mBubbleSectionView.setOnClickListener(view -> {
+ onClose.run();
+ });
+ }
+
+ /**
+ * Overridden to proxy to section views alpha.
+ * @implNote
+ * If animate alpha on the parent (menu container) view, section view shadows get distorted.
+ * To prevent distortion and artifacts alpha changes applied directly on the section views.
+ */
+ @Override
+ public void setAlpha(float alpha) {
+ mBubbleSectionView.setAlpha(alpha);
+ mActionsSectionView.setAlpha(alpha);
+ }
+
+ /**
+ * Overridden to proxy section view alpha value.
+ * @implNote
+ * The assumption is that both section views have the same alpha value
+ */
+ @Override
+ public float getAlpha() {
+ return mBubbleSectionView.getAlpha();
+ }
+
+ /**
+ * Menu action details used to create menu items
+ */
+ static class MenuAction {
+ private Icon mIcon;
+ private @ColorInt int mTint;
+ private String mTitle;
+ private OnClickListener mOnClick;
+
+ MenuAction(Icon icon, String title, OnClickListener onClick) {
+ this(icon, title, Color.TRANSPARENT, onClick);
+ }
+
+ MenuAction(Icon icon, String title, @ColorInt int tint, OnClickListener onClick) {
+ this.mIcon = icon;
+ this.mTitle = title;
+ this.mTint = tint;
+ this.mOnClick = onClick;
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
new file mode 100644
index 000000000000..8be140c16435
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Icon;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.core.content.ContextCompat;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.Bubble;
+
+import java.util.ArrayList;
+
+/**
+ * Manages bubble bar expanded view menu presentation and animations
+ */
+class BubbleBarMenuViewController {
+ private static final float MENU_INITIAL_SCALE = 0.5f;
+ private final Context mContext;
+ private final ViewGroup mRootView;
+ private @Nullable Listener mListener;
+ private @Nullable Bubble mBubble;
+ private @Nullable BubbleBarMenuView mMenuView;
+ /** A transparent view used to intercept touches to collapse menu when presented */
+ private @Nullable View mScrimView;
+ private @Nullable PhysicsAnimator<BubbleBarMenuView> mMenuAnimator;
+ private PhysicsAnimator.SpringConfig mMenuSpringConfig;
+
+ BubbleBarMenuViewController(Context context, ViewGroup rootView) {
+ mContext = context;
+ mRootView = rootView;
+ mMenuSpringConfig = new PhysicsAnimator.SpringConfig(
+ SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+ }
+
+ /** Sets menu actions listener */
+ void setListener(@Nullable Listener listener) {
+ mListener = listener;
+ }
+
+ /** Update menu with bubble */
+ void updateMenu(@NonNull Bubble bubble) {
+ mBubble = bubble;
+ }
+
+ /**
+ * Show bubble bar expanded view menu
+ * @param animated if should animate transition
+ */
+ void showMenu(boolean animated) {
+ if (mMenuView == null || mScrimView == null) {
+ setupMenu();
+ }
+ cancelAnimations();
+ mMenuView.setVisibility(View.VISIBLE);
+ mScrimView.setVisibility(View.VISIBLE);
+ Runnable endActions = () -> {
+ mMenuView.getChildAt(0).requestAccessibilityFocus();
+ if (mListener != null) {
+ mListener.onMenuVisibilityChanged(true /* isShown */);
+ }
+ };
+ if (animated) {
+ animateTransition(true /* show */, endActions);
+ } else {
+ endActions.run();
+ }
+ }
+
+ /**
+ * Hide bubble bar expanded view menu
+ * @param animated if should animate transition
+ */
+ void hideMenu(boolean animated) {
+ if (mMenuView == null || mScrimView == null) return;
+ cancelAnimations();
+ Runnable endActions = () -> {
+ mMenuView.setVisibility(View.GONE);
+ mScrimView.setVisibility(View.GONE);
+ if (mListener != null) {
+ mListener.onMenuVisibilityChanged(false /* isShown */);
+ }
+ };
+ if (animated) {
+ animateTransition(false /* show */, endActions);
+ } else {
+ endActions.run();
+ }
+ }
+
+ /**
+ * Animate show/hide menu transition
+ * @param show if should show or hide the menu
+ * @param endActions will be called when animation ends
+ */
+ private void animateTransition(boolean show, Runnable endActions) {
+ if (mMenuView == null) return;
+ mMenuAnimator = PhysicsAnimator.getInstance(mMenuView);
+ mMenuAnimator.setDefaultSpringConfig(mMenuSpringConfig);
+ mMenuAnimator
+ .spring(DynamicAnimation.ALPHA, show ? 1f : 0f)
+ .spring(DynamicAnimation.SCALE_Y, show ? 1f : MENU_INITIAL_SCALE)
+ .withEndActions(() -> {
+ mMenuAnimator = null;
+ endActions.run();
+ })
+ .start();
+ }
+
+ /** Cancel running animations */
+ private void cancelAnimations() {
+ if (mMenuAnimator != null) {
+ mMenuAnimator.cancel();
+ mMenuAnimator = null;
+ }
+ }
+
+ /** Sets up and inflate menu views */
+ private void setupMenu() {
+ // Menu view setup
+ mMenuView = (BubbleBarMenuView) LayoutInflater.from(mContext).inflate(
+ R.layout.bubble_bar_menu_view, mRootView, false);
+ mMenuView.setAlpha(0f);
+ mMenuView.setPivotY(0f);
+ mMenuView.setScaleY(MENU_INITIAL_SCALE);
+ mMenuView.setOnCloseListener(() -> hideMenu(true /* animated */));
+ if (mBubble != null) {
+ mMenuView.updateInfo(mBubble);
+ mMenuView.updateActions(createMenuActions(mBubble));
+ }
+ // Scrim view setup
+ mScrimView = new View(mContext);
+ mScrimView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ mScrimView.setOnClickListener(view -> hideMenu(true /* animated */));
+ // Attach to root view
+ mRootView.addView(mScrimView);
+ mRootView.addView(mMenuView);
+ }
+
+ /**
+ * Creates menu actions to populate menu view
+ * @param bubble used to create actions depending on bubble type
+ */
+ private ArrayList<BubbleBarMenuView.MenuAction> createMenuActions(Bubble bubble) {
+ ArrayList<BubbleBarMenuView.MenuAction> menuActions = new ArrayList<>();
+ Resources resources = mContext.getResources();
+
+ if (bubble.isConversation()) {
+ // Don't bubble conversation action
+ menuActions.add(new BubbleBarMenuView.MenuAction(
+ Icon.createWithResource(mContext, R.drawable.bubble_ic_stop_bubble),
+ resources.getString(R.string.bubbles_dont_bubble_conversation),
+ view -> {
+ hideMenu(true /* animated */);
+ if (mListener != null) {
+ mListener.onUnBubbleConversation(bubble);
+ }
+ }
+ ));
+ // Open settings action
+ Icon appIcon = bubble.getRawAppBadge() != null ? Icon.createWithBitmap(
+ bubble.getRawAppBadge()) : null;
+ menuActions.add(new BubbleBarMenuView.MenuAction(
+ appIcon,
+ resources.getString(R.string.bubbles_app_settings, bubble.getAppName()),
+ view -> {
+ hideMenu(true /* animated */);
+ if (mListener != null) {
+ mListener.onOpenAppSettings(bubble);
+ }
+ }
+ ));
+ }
+
+ // Dismiss bubble action
+ menuActions.add(new BubbleBarMenuView.MenuAction(
+ Icon.createWithResource(resources, R.drawable.ic_remove_no_shadow),
+ resources.getString(R.string.bubble_dismiss_text),
+ ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_menu_close),
+ view -> {
+ hideMenu(true /* animated */);
+ if (mListener != null) {
+ mListener.onDismissBubble(bubble);
+ }
+ }
+ ));
+
+ return menuActions;
+ }
+
+ /**
+ * Bubble bar expanded view menu actions listener
+ */
+ interface Listener {
+ /**
+ * Called when manage menu is shown/hidden
+ * If animated will be called when animation ends
+ */
+ void onMenuVisibilityChanged(boolean visible);
+
+ /**
+ * Un-bubbles conversation and removes the bubble from the stack
+ * This conversation will not be bubbled with new messages
+ * @see com.android.wm.shell.bubbles.BubbleController
+ */
+ void onUnBubbleConversation(Bubble bubble);
+
+ /**
+ * Launches app notification bubble settings for the bubble with intent created in:
+ * {@code Bubble.getSettingsIntent}
+ */
+ void onOpenAppSettings(Bubble bubble);
+
+ /**
+ * Dismiss bubble and remove it from the bubble stack
+ */
+ void onDismissBubble(Bubble bubble);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
new file mode 100644
index 000000000000..81592c35e4ac
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.common
+
+import android.window.WindowContainerToken
+import android.window.WindowContainerTransaction
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG
+import com.android.wm.shell.util.KtProtoLog
+
+/**
+ * Controller to manage behavior of activities launched with
+ * [android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT].
+ */
+class LaunchAdjacentController(private val syncQueue: SyncTransactionQueue) {
+
+ /** Allows to temporarily disable launch adjacent handling */
+ var launchAdjacentEnabled: Boolean = true
+ set(value) {
+ if (field != value) {
+ KtProtoLog.d(WM_SHELL_TASK_ORG, "set launch adjacent flag root enabled=%b", value)
+ field = value
+ container?.let { c ->
+ if (value) {
+ enableContainer(c)
+ } else {
+ disableContainer((c))
+ }
+ }
+ }
+ }
+ private var container: WindowContainerToken? = null
+
+ /**
+ * Set [container] as the new launch adjacent flag root container.
+ *
+ * If launch adjacent handling is disabled through [setLaunchAdjacentEnabled], won't set the
+ * container until after it is enabled again.
+ *
+ * @see WindowContainerTransaction.setLaunchAdjacentFlagRoot
+ */
+ fun setLaunchAdjacentRoot(container: WindowContainerToken) {
+ KtProtoLog.d(WM_SHELL_TASK_ORG, "set new launch adjacent flag root container")
+ this.container = container
+ if (launchAdjacentEnabled) {
+ enableContainer(container)
+ }
+ }
+
+ /**
+ * Clear a container previously set through [setLaunchAdjacentRoot].
+ *
+ * Always clears the container, regardless of [launchAdjacentEnabled] value.
+ *
+ * @see WindowContainerTransaction.clearLaunchAdjacentFlagRoot
+ */
+ fun clearLaunchAdjacentRoot() {
+ KtProtoLog.d(WM_SHELL_TASK_ORG, "clear launch adjacent flag root container")
+ container?.let {
+ disableContainer(it)
+ container = null
+ }
+ }
+
+ private fun enableContainer(container: WindowContainerToken) {
+ KtProtoLog.v(WM_SHELL_TASK_ORG, "enable launch adjacent flag root container")
+ val wct = WindowContainerTransaction()
+ wct.setLaunchAdjacentFlagRoot(container)
+ syncQueue.queue(wct)
+ }
+
+ private fun disableContainer(container: WindowContainerToken) {
+ KtProtoLog.v(WM_SHELL_TASK_ORG, "disable launch adjacent flag root container")
+ val wct = WindowContainerTransaction()
+ wct.clearLaunchAdjacentFlagRoot(container)
+ syncQueue.queue(wct)
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
index ac6e4c2a6521..53683c67d825 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
@@ -54,14 +54,6 @@ public class TabletopModeController implements
DevicePostureController.OnDevicePostureChangedListener,
DisplayController.OnDisplaysChangedListener {
/**
- * When {@code true}, floating windows like PiP would auto move to the position
- * specified by {@link #PREFER_TOP_HALF_IN_TABLETOP} when in tabletop mode.
- */
- private static final boolean ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
- SystemProperties.getBoolean(
- "persist.wm.debug.enable_move_floating_window_in_tabletop", true);
-
- /**
* Prefer the {@link #PREFERRED_TABLETOP_HALF_TOP} if this flag is enabled,
* {@link #PREFERRED_TABLETOP_HALF_BOTTOM} otherwise.
* See also {@link #getPreferredHalfInTabletopMode()}.
@@ -162,14 +154,6 @@ public class TabletopModeController implements
}
}
- /**
- * @return {@code true} if floating windows like PiP would auto move to the position
- * specified by {@link #getPreferredHalfInTabletopMode()} when in tabletop mode.
- */
- public boolean enableMoveFloatingWindowInTabletop() {
- return ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP;
- }
-
/** @return Preferred half for floating windows like PiP when in tabletop mode. */
@PreferredTabletopHalf
public int getPreferredHalfInTabletopMode() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
index c76937de6669..ec2680085fb5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
@@ -76,6 +76,9 @@ public class DividerHandleView extends View {
private int mCurrentHeight;
private AnimatorSet mAnimator;
private boolean mTouching;
+ private boolean mHovering;
+ private final int mHoveringWidth;
+ private final int mHoveringHeight;
public DividerHandleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -87,6 +90,8 @@ public class DividerHandleView extends View {
mCurrentHeight = mHeight;
mTouchingWidth = mWidth > mHeight ? mWidth / 2 : mWidth;
mTouchingHeight = mHeight > mWidth ? mHeight / 2 : mHeight;
+ mHoveringWidth = mWidth > mHeight ? ((int) (mWidth * 1.5f)) : mWidth;
+ mHoveringHeight = mHeight > mWidth ? ((int) (mHeight * 1.5f)) : mHeight;
}
/** Sets touching state for this handle view. */
@@ -94,24 +99,32 @@ public class DividerHandleView extends View {
if (touching == mTouching) {
return;
}
+ setInputState(touching, animate, mTouchingWidth, mTouchingHeight);
+ mTouching = touching;
+ }
+
+ /** Sets hovering state for this handle view. */
+ public void setHovering(boolean hovering, boolean animate) {
+ if (hovering == mHovering) {
+ return;
+ }
+ setInputState(hovering, animate, mHoveringWidth, mHoveringHeight);
+ mHovering = hovering;
+ }
+
+ private void setInputState(boolean stateOn, boolean animate, int stateWidth, int stateHeight) {
if (mAnimator != null) {
mAnimator.cancel();
mAnimator = null;
}
if (!animate) {
- if (touching) {
- mCurrentWidth = mTouchingWidth;
- mCurrentHeight = mTouchingHeight;
- } else {
- mCurrentWidth = mWidth;
- mCurrentHeight = mHeight;
- }
+ mCurrentWidth = stateOn ? stateWidth : mWidth;
+ mCurrentHeight = stateOn ? stateHeight : mHeight;
invalidate();
} else {
- animateToTarget(touching ? mTouchingWidth : mWidth,
- touching ? mTouchingHeight : mHeight, touching);
+ animateToTarget(stateOn ? stateWidth : mWidth,
+ stateOn ? stateHeight : mHeight, stateOn);
}
- mTouching = touching;
}
private void animateToTarget(int targetWidth, int targetHeight, boolean touching) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 69f0bad4fb45..262d487b1d1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -17,14 +17,19 @@
package com.android.wm.shell.common.split;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
+import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CURSOR_HOVER_STATES_ENABLED;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
+import android.provider.DeviceConfig;
import android.util.AttributeSet;
import android.util.Property;
import android.view.GestureDetector;
@@ -32,6 +37,7 @@ import android.view.InsetsController;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.MotionEvent;
+import android.view.PointerIcon;
import android.view.SurfaceControlViewHost;
import android.view.VelocityTracker;
import android.view.View;
@@ -46,6 +52,7 @@ import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
@@ -222,7 +229,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
for (int i = insetsState.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = insetsState.sourceAt(i);
if (source.getType() == WindowInsets.Type.navigationBars()
- && source.insetsRoundedCornerFrame()) {
+ && source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
mTempRect.inset(source.calculateVisibleInsets(mTempRect));
}
}
@@ -270,6 +277,12 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
}
@Override
+ public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
+ return PointerIcon.getSystemIcon(getContext(),
+ isLandscape() ? TYPE_HORIZONTAL_DOUBLE_ARROW : TYPE_VERTICAL_DOUBLE_ARROW);
+ }
+
+ @Override
public boolean onTouch(View v, MotionEvent event) {
if (mSplitLayout == null || !mInteractive) {
return false;
@@ -371,6 +384,43 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
mViewHost.relayout(lp);
}
+ @Override
+ public boolean onHoverEvent(MotionEvent event) {
+ if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, CURSOR_HOVER_STATES_ENABLED,
+ /* defaultValue = */ false)) {
+ return false;
+ }
+
+ if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
+ setHovering();
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
+ releaseHovering();
+ return true;
+ }
+ return false;
+ }
+
+ @VisibleForTesting
+ void setHovering() {
+ mHandle.setHovering(true, true);
+ mHandle.animate()
+ .setInterpolator(Interpolators.TOUCH_RESPONSE)
+ .setDuration(TOUCH_ANIMATION_DURATION)
+ .translationZ(mTouchElevation)
+ .start();
+ }
+
+ @VisibleForTesting
+ void releaseHovering() {
+ mHandle.setHovering(false, true);
+ mHandle.animate()
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
+ .translationZ(0)
+ .start();
+ }
+
/**
* Set divider should interactive to user or not.
*
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index 753dfa7396f8..a9ccdf6a156f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -293,6 +293,9 @@ public class SplitDecorManager extends WindowlessWindowManager {
}
if (mResizingIconView == null) {
+ if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
+ animFinishedCallback.accept(false);
+ }
return;
}
@@ -311,6 +314,9 @@ public class SplitDecorManager extends WindowlessWindowManager {
releaseDecor(finishT);
finishT.apply();
finishT.close();
+ if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
+ animFinishedCallback.accept(true);
+ }
}
});
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index bc0b71c97346..2dbccaceeddc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -542,9 +542,12 @@ public abstract class WMShellModule {
Optional<PipTouchHandler> pipTouchHandlerOptional,
Optional<RecentsTransitionHandler> recentsTransitionHandler,
KeyguardTransitionHandler keyguardTransitionHandler,
+ Optional<DesktopModeController> desktopModeController,
+ Optional<DesktopTasksController> desktopTasksController,
Transitions transitions) {
return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
- pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler);
+ pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler,
+ desktopModeController, desktopTasksController);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index 1169af9306b0..db6c258e84c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -33,6 +33,7 @@ import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DE
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration;
import android.content.Context;
+import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Region;
import android.net.Uri;
@@ -414,6 +415,25 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
}
/**
+ * Applies the proper surface states (rounded corners) to tasks when desktop mode is active.
+ * This is intended to be used when desktop mode is part of another animation but isn't, itself,
+ * animating.
+ */
+ public void syncSurfaceState(@NonNull TransitionInfo info,
+ SurfaceControl.Transaction finishTransaction) {
+ // Add rounded corners to freeform windows
+ final TypedArray ta = mContext.obtainStyledAttributes(
+ new int[]{android.R.attr.dialogCornerRadius});
+ final int cornerRadius = ta.getDimensionPixelSize(0, 0);
+ ta.recycle();
+ for (TransitionInfo.Change change: info.getChanges()) {
+ if (change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ finishTransaction.setCornerRadius(change.getLeash(), cornerRadius);
+ }
+ }
+ }
+
+ /**
* A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE}
*/
private final class SettingsObserver extends ContentObserver {
@@ -500,6 +520,11 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
}
@Override
+ public void showDesktopApp(int taskId) throws RemoteException {
+ // TODO
+ }
+
+ @Override
public int getVisibleTaskCount(int displayId) throws RemoteException {
int[] result = new int[1];
executeRemoteCallWithTaskPermission(mController, "getVisibleTaskCount",
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 de7d3adb0af3..37cbbcd1853a 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
@@ -16,6 +16,7 @@
package com.android.wm.shell.desktopmode
+import android.R
import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
@@ -24,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.app.WindowConfiguration.WindowingMode
import android.content.Context
+import android.content.res.TypedArray
import android.graphics.Point
import android.graphics.Rect
import android.graphics.Region
@@ -277,6 +279,11 @@ class DesktopTasksController(
}
/** Move a task to the front */
+ fun moveTaskToFront(taskId: Int) {
+ shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveTaskToFront(task) }
+ }
+
+ /** Move a task to the front */
fun moveTaskToFront(taskInfo: RunningTaskInfo) {
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
@@ -460,6 +467,25 @@ class DesktopTasksController(
}
}
+ /**
+ * Applies the proper surface states (rounded corners) to tasks when desktop mode is active.
+ * This is intended to be used when desktop mode is part of another animation but isn't, itself,
+ * animating.
+ */
+ fun syncSurfaceState(
+ info: TransitionInfo,
+ finishTransaction: SurfaceControl.Transaction
+ ) {
+ // Add rounded corners to freeform windows
+ val ta: TypedArray = context.obtainStyledAttributes(
+ intArrayOf(R.attr.dialogCornerRadius))
+ val cornerRadius = ta.getDimensionPixelSize(0, 0).toFloat()
+ ta.recycle()
+ info.changes
+ .filter { it.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM }
+ .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
+ }
+
private fun handleFreeformTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? {
val activeTasks = desktopModeTaskRepository.getActiveTasks(task.displayId)
if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) {
@@ -574,14 +600,16 @@ class DesktopTasksController(
* Perform checks required on drag end. Move to fullscreen if drag ends in status bar area.
*
* @param taskInfo the task being dragged.
- * @param position position of surface when drag ends
+ * @param position position of surface when drag ends.
+ * @param y the Y position of the motion event.
*/
fun onDragPositioningEnd(
taskInfo: RunningTaskInfo,
- position: Point
+ position: Point,
+ y: Float
) {
val statusBarHeight = getStatusBarHeight(taskInfo)
- if (position.y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
+ if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
moveToFullscreenWithAnimation(taskInfo, position)
}
}
@@ -772,6 +800,13 @@ class DesktopTasksController(
) { c -> c.hideStashedDesktopApps(displayId) }
}
+ override fun showDesktopApp(taskId: Int) {
+ ExecutorUtils.executeRemoteCallWithTaskPermission(
+ controller,
+ "showDesktopApp"
+ ) { c -> c.moveTaskToFront(taskId) }
+ }
+
override fun getVisibleTaskCount(displayId: Int): Int {
val result = IntArray(1)
ExecutorUtils.executeRemoteCallWithTaskPermission(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index 05a6e33de37a..ee3a080e7318 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -32,6 +32,9 @@ interface IDesktopMode {
/** Hide apps that may be stashed */
void hideStashedDesktopApps(int displayId);
+ /** Bring task with the given id to front */
+ oneway void showDesktopApp(int taskId);
+
/** Get count of visible desktop tasks on the given display */
int getVisibleTaskCount(int displayId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 4d8075a9b56c..513638eeb960 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -121,21 +121,21 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
}
boolean hasOpeningOcclude = false;
+ boolean hasClosingOcclude = false;
boolean hasOpeningDream = false;
boolean hasClosingApp = false;
// Check for occluding/dream/closing apps
for (int i = info.getChanges().size() - 1; i >= 0; i--) {
final TransitionInfo.Change change = info.getChanges().get(i);
- if (isOpeningType(change.getMode())) {
- if (change.hasFlags(FLAG_OCCLUDES_KEYGUARD)) {
- hasOpeningOcclude = true;
- }
- if (change.getTaskInfo() != null
- && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM) {
- hasOpeningDream = true;
- }
+ if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) {
+ continue;
+ } else if (isOpeningType(change.getMode())) {
+ hasOpeningOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
+ hasOpeningDream |= (change.getTaskInfo() != null
+ && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM);
} else if (isClosingType(change.getMode())) {
+ hasClosingOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
hasClosingApp = true;
}
}
@@ -147,6 +147,11 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
transition, info, startTransaction, finishTransaction, finishCallback);
}
if (hasOpeningOcclude || info.getType() == TRANSIT_KEYGUARD_OCCLUDE) {
+ if (hasClosingOcclude) {
+ // Transitions between apps on top of the keyguard can use the default handler.
+ // WM sends a final occlude status update after the transition is finished.
+ return false;
+ }
if (hasOpeningDream) {
return startAnimation(mOccludeByDreamTransition,
"occlude-by-dream",
@@ -161,7 +166,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
"unocclude",
transition, info, startTransaction, finishTransaction, finishCallback);
} else {
- Log.wtf(TAG, "Failed to play: " + info);
+ Log.w(TAG, "Failed to play: " + info);
return false;
}
}
@@ -180,7 +185,11 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
@Override
public void onTransitionFinished(
WindowContainerTransaction wct, SurfaceControl.Transaction sct) {
+ if (sct != null) {
+ finishTransaction.merge(sct);
+ }
mMainExecutor.execute(() -> {
+ mStartedTransitions.remove(transition);
finishCallback.onTransitionFinished(wct, null);
});
}
@@ -201,7 +210,7 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
final IRemoteTransition playing = mStartedTransitions.get(currentTransition);
if (playing == null) {
- ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
"unknown keyguard transition %s", currentTransition);
return;
}
@@ -212,14 +221,17 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
// the device sleeping/waking, so it's best to ignore this and keep playing anyway.
return;
} else {
- finishAnimationImmediately(currentTransition);
+ finishAnimationImmediately(currentTransition, playing);
}
}
@Override
public void onTransitionConsumed(IBinder transition, boolean aborted,
SurfaceControl.Transaction finishTransaction) {
- finishAnimationImmediately(transition);
+ final IRemoteTransition playing = mStartedTransitions.remove(transition);
+ if (playing != null) {
+ finishAnimationImmediately(transition, playing);
+ }
}
@Nullable
@@ -229,21 +241,17 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
return null;
}
- private void finishAnimationImmediately(IBinder transition) {
- final IRemoteTransition playing = mStartedTransitions.get(transition);
-
- if (playing != null) {
- final IBinder fakeTransition = new Binder();
- final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
- final SurfaceControl.Transaction fakeT = new SurfaceControl.Transaction();
- final FakeFinishCallback fakeFinishCb = new FakeFinishCallback();
- try {
- playing.mergeAnimation(fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
- } catch (RemoteException e) {
- // There is no good reason for this to happen because the player is a local object
- // implementing an AIDL interface.
- Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
- }
+ private void finishAnimationImmediately(IBinder transition, IRemoteTransition playing) {
+ final IBinder fakeTransition = new Binder();
+ final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
+ final SurfaceControl.Transaction fakeT = new SurfaceControl.Transaction();
+ final FakeFinishCallback fakeFinishCb = new FakeFinishCallback();
+ try {
+ playing.mergeAnimation(fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
+ } catch (RemoteException e) {
+ // There is no good reason for this to happen because the player is a local object
+ // implementing an AIDL interface.
+ Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
index 65a12d629c5a..2590cab9ff2e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
@@ -252,13 +252,16 @@ public class PipMediaController {
// It can be removed when min_sdk of the app is set to 31 or greater.
@SuppressLint("NewApi")
private List<RemoteAction> getMediaActions() {
- if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+ // Cache the PlaybackState since it's a Binder call.
+ final PlaybackState playbackState;
+ if (mMediaController == null
+ || (playbackState = mMediaController.getPlaybackState()) == null) {
return Collections.emptyList();
}
ArrayList<RemoteAction> mediaActions = new ArrayList<>();
- boolean isPlaying = mMediaController.getPlaybackState().isActive();
- long actions = mMediaController.getPlaybackState().getActions();
+ boolean isPlaying = playbackState.isActive();
+ long actions = playbackState.getActions();
// Prev action
mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index bfc1fb905ade..f9d615ad0cf6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -53,6 +53,7 @@ import android.os.SystemProperties;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManager;
+import android.window.TaskSnapshot;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerToken;
@@ -249,11 +250,6 @@ public class PipTransition extends PipTransitionController {
finishTransaction);
}
- // Fade in the fadeout PIP when the fixed rotation is finished.
- if (mPipTransitionState.isInPip() && !mInFixedRotation && mHasFadeOut) {
- fadeExistingPip(true /* show */);
- }
-
return false;
}
@@ -880,6 +876,14 @@ public class PipTransition extends PipTransitionController {
} else {
animator.setColorContentOverlay(mContext);
}
+ } else {
+ final TaskSnapshot snapshot = PipUtils.getTaskSnapshot(
+ taskInfo.launchIntoPipHostTaskId, false /* isLowResolution */);
+ if (snapshot != null) {
+ // use the task snapshot during the animation, this is for
+ // launch-into-pip aka. content-pip use case.
+ animator.setSnapshotContentOverlay(snapshot, sourceHintRect);
+ }
}
} else if (enterAnimationType == ANIM_TYPE_ALPHA) {
animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
@@ -1056,6 +1060,12 @@ public class PipTransition extends PipTransitionController {
.crop(finishTransaction, leash, destBounds)
.round(finishTransaction, leash, isInPip)
.shadow(finishTransaction, leash, isInPip);
+ // Make sure the PiP keeps invisible if it was faded out. If it needs to fade in, that will
+ // be handled by onFixedRotationFinished().
+ if (isInPip && mHasFadeOut) {
+ startTransaction.setAlpha(leash, 0f);
+ finishTransaction.setAlpha(leash, 0f);
+ }
}
/** Hides and shows the existing PIP during fixed rotation transition of other activities. */
@@ -1069,10 +1079,28 @@ public class PipTransition extends PipTransitionController {
}
final float alphaStart = show ? 0 : 1;
final float alphaEnd = show ? 1 : 0;
+ final PipAnimationController.PipTransactionHandler transactionHandler =
+ new PipAnimationController.PipTransactionHandler() {
+ @Override
+ public boolean handlePipTransaction(SurfaceControl leash,
+ SurfaceControl.Transaction tx, Rect destinationBounds, float alpha) {
+ if (alpha == 0) {
+ if (show) {
+ tx.setPosition(leash, destinationBounds.left, destinationBounds.top);
+ } else {
+ // Put PiP out of the display so it won't block touch when it is hidden.
+ final Rect displayBounds = mPipDisplayLayoutState.getDisplayBounds();
+ final int max = Math.max(displayBounds.width(), displayBounds.height());
+ tx.setPosition(leash, max, max);
+ }
+ }
+ return false;
+ }
+ };
mPipAnimationController
.getAnimator(taskInfo, leash, mPipBoundsState.getBounds(), alphaStart, alphaEnd)
.setTransitionDirection(TRANSITION_DIRECTION_SAME)
- .setPipAnimationCallback(mPipAnimationCallback)
+ .setPipTransactionHandler(transactionHandler)
.setDuration(mEnterExitAnimationDuration)
.start();
mHasFadeOut = !show;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 63181da46b02..6a861ce97431 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -677,7 +677,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb
});
mTabletopModeController.registerOnTabletopModeChangedListener((isInTabletopMode) -> {
- if (!mTabletopModeController.enableMoveFloatingWindowInTabletop()) return;
final String tag = "tabletop-mode";
if (!isInTabletopMode) {
mPipBoundsState.removeNamedUnrestrictedKeepClearArea(tag);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 167c0321d3ad..779c539a2097 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -45,6 +45,7 @@ import android.content.Intent;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -513,13 +514,19 @@ public class PipMenuView extends FrameLayout {
final boolean isCloseAction = mCloseAction != null && Objects.equals(
mCloseAction.getActionIntent(), action.getActionIntent());
- // TODO: Check if the action drawable has changed before we reload it
- action.getIcon().loadDrawableAsync(mContext, d -> {
- if (d != null) {
- d.setTint(Color.WHITE);
- actionView.setImageDrawable(d);
- }
- }, mMainHandler);
+ final int iconType = action.getIcon().getType();
+ if (iconType == Icon.TYPE_URI || iconType == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
+ // Disallow loading icon from content URI
+ actionView.setImageDrawable(null);
+ } else {
+ // TODO: Check if the action drawable has changed before we reload it
+ action.getIcon().loadDrawableAsync(mContext, d -> {
+ if (d != null) {
+ d.setTint(Color.WHITE);
+ actionView.setImageDrawable(d);
+ }
+ }, mMainHandler);
+ }
actionView.setCustomCloseBackgroundVisibility(
isCloseAction ? View.VISIBLE : View.GONE);
actionView.setContentDescription(action.getContentDescription());
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 5c9709c756f7..f35eda6caef0 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
@@ -371,7 +371,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
* Find the background task that match the given component.
*/
@Nullable
- public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName) {
+ public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName,
+ int userId) {
if (componentName == null) {
return null;
}
@@ -383,7 +384,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
if (task.isVisible) {
continue;
}
- if (componentName.equals(task.baseIntent.getComponent())) {
+ if (componentName.equals(task.baseIntent.getComponent()) && userId == task.userId) {
return task;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index a9ad3c90949f..8723f9b0181d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -35,6 +35,8 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
+import android.util.IntArray;
+import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.IRecentsAnimationController;
@@ -135,8 +137,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
@Override
public WindowContainerTransaction handleRequest(IBinder transition,
TransitionRequestInfo request) {
- // do not directly handle requests. Only entry point should be via startRecentsTransition
- // TODO: Only log an error if the transition is a recents transition
+ if (mControllers.isEmpty()) {
+ // Ignore if there is no running recents transition
+ return null;
+ }
+ final RecentsController controller = mControllers.get(mControllers.size() - 1);
+ controller.handleMidTransitionRequest(request);
return null;
}
@@ -239,6 +245,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
/** The latest state that the recents animation is operating in. */
private int mState = STATE_NORMAL;
+ // Snapshots taken when a new display change transition is requested, prior to the display
+ // change being applied. This pending set of snapshots will only be applied when cancel is
+ // next called.
+ private Pair<int[], TaskSnapshot[]> mPendingPauseSnapshotsForCancel;
+
RecentsController(IRecentsAnimationRunner listener) {
mInstanceId = System.identityHashCode(this);
mListener = listener;
@@ -264,21 +275,18 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
void cancel(String reason) {
// restoring (to-home = false) involves submitting more WM changes, so by default, use
// toHome = true when canceling.
- cancel(true /* toHome */, reason);
+ cancel(true /* toHome */, false /* withScreenshots */, reason);
}
- void cancel(boolean toHome, String reason) {
+ void cancel(boolean toHome, boolean withScreenshots, String reason) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.cancel: toHome=%b reason=%s",
mInstanceId, toHome, reason);
if (mListener != null) {
- try {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- "[%d] RecentsController.cancel: calling onAnimationCanceled",
- mInstanceId);
- mListener.onAnimationCanceled(null, null);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error canceling recents animation", e);
+ if (withScreenshots) {
+ sendCancelWithSnapshots();
+ } else {
+ sendCancel(null, null);
}
}
if (mFinishCB != null) {
@@ -293,6 +301,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
* "replace-with-screenshot" like behavior.
*/
private boolean sendCancelWithSnapshots() {
+ Pair<int[], TaskSnapshot[]> snapshots = mPendingPauseSnapshotsForCancel != null
+ ? mPendingPauseSnapshotsForCancel
+ : getSnapshotsForPausingTasks();
+ return sendCancel(snapshots.first, snapshots.second);
+ }
+
+ /**
+ * Snapshots the pausing tasks and returns the mapping of the taskId -> snapshot.
+ */
+ private Pair<int[], TaskSnapshot[]> getSnapshotsForPausingTasks() {
int[] taskIds = null;
TaskSnapshot[] snapshots = null;
if (mPausingTasks.size() > 0) {
@@ -300,24 +318,37 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
snapshots = new TaskSnapshot[mPausingTasks.size()];
try {
for (int i = 0; i < mPausingTasks.size(); ++i) {
+ TaskState state = mPausingTasks.get(0);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.sendCancel: Snapshotting task=%d",
+ mInstanceId, state.mTaskInfo.taskId);
snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
- mPausingTasks.get(0).mTaskInfo.taskId, false /* updateCache */);
+ state.mTaskInfo.taskId, true /* updateCache */);
}
} catch (RemoteException e) {
taskIds = null;
snapshots = null;
}
}
+ return new Pair(taskIds, snapshots);
+ }
+
+ /**
+ * Sends a cancel message to the recents animation.
+ */
+ private boolean sendCancel(@Nullable int[] taskIds,
+ @Nullable TaskSnapshot[] taskSnapshots) {
try {
+ final String cancelDetails = taskSnapshots != null ? "with snapshots" : "";
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- "[%d] RecentsController.cancel: calling onAnimationCanceled with snapshots",
- mInstanceId);
- mListener.onAnimationCanceled(taskIds, snapshots);
+ "[%d] RecentsController.cancel: calling onAnimationCanceled %s",
+ mInstanceId, cancelDetails);
+ mListener.onAnimationCanceled(taskIds, taskSnapshots);
+ return true;
} catch (RemoteException e) {
Slog.e(TAG, "Error canceling recents animation", e);
return false;
}
- return true;
}
void cleanUp() {
@@ -341,6 +372,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mOpeningTasks = null;
mInfo = null;
mTransition = null;
+ mPendingPauseSnapshotsForCancel = null;
mControllers.remove(this);
}
@@ -391,26 +423,28 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// About layering: we divide up the "layer space" into 3 regions (each the size of
// the change count). This lets us categorize things into above/below/between
// while maintaining their relative ordering.
+ final int belowLayers = info.getChanges().size();
+ final int aboveLayers = info.getChanges().size() * 3;
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (TransitionUtil.isWallpaper(change)) {
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
// wallpapers go into the "below" layer space
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
wallpapers.add(target);
// Make all the wallpapers opaque since we want them visible from the start
t.setAlpha(target.leash, 1);
} else if (leafTaskFilter.test(change)) {
// start by putting everything into the "below" layer space.
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
apps.add(target);
if (TransitionUtil.isClosingType(change.getMode())) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " adding pausing taskId=%d", taskInfo.taskId);
+ " adding pausing leaf taskId=%d", taskInfo.taskId);
// raise closing (pausing) task to "above" layer so it isn't covered
- t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ t.setLayer(target.leash, aboveLayers - i);
mPausingTasks.add(new TaskState(change, target.leash));
if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// This can only happen if we have a separate recents/home (3p launcher)
@@ -423,17 +457,32 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
} else if (taskInfo != null
&& taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
// There's a 3p launcher, so make sure recents goes above that.
- t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ t.setLayer(target.leash, aboveLayers - i);
} else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// do nothing
} else if (TransitionUtil.isOpeningType(change.getMode())) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " adding opening taskId=%d", taskInfo.taskId);
+ " adding opening leaf taskId=%d", taskInfo.taskId);
mOpeningTasks.add(new TaskState(change, target.leash));
}
+ } else if (taskInfo != null && TransitionInfo.isIndependent(change, info)) {
+ // Root tasks
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " adding pausing taskId=%d", taskInfo.taskId);
+ // raise closing (pausing) task to "above" layer so it isn't covered
+ t.setLayer(change.getLeash(), aboveLayers - i);
+ mPausingTasks.add(new TaskState(change, null /* leash */));
+ } else if (TransitionUtil.isOpeningType(change.getMode())) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " adding opening taskId=%d", taskInfo.taskId);
+ // Put into the "below" layer space.
+ t.setLayer(change.getLeash(), belowLayers - i);
+ mOpeningTasks.add(new TaskState(change, null /* leash */));
+ }
} else if (TransitionUtil.isDividerBar(change)) {
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
- info.getChanges().size() - i, info, t, mLeashMap);
+ belowLayers - i, info, t, mLeashMap);
// Add this as a app and we will separate them on launcher side by window type.
apps.add(target);
}
@@ -453,6 +502,22 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return true;
}
+ /**
+ * Updates this controller when a new transition is requested mid-recents transition.
+ */
+ void handleMidTransitionRequest(TransitionRequestInfo request) {
+ if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) {
+ final TransitionRequestInfo.DisplayChange dispChange = request.getDisplayChange();
+ if (dispChange.getStartRotation() != dispChange.getEndRotation()) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.prepareForMerge: "
+ + "Snapshot due to requested display change",
+ mInstanceId);
+ mPendingPauseSnapshotsForCancel = getSnapshotsForPausingTasks();
+ }
+ }
+ }
+
@SuppressLint("NewApi")
void merge(TransitionInfo info, SurfaceControl.Transaction t,
Transitions.TransitionFinishCallback finishCallback) {
@@ -472,7 +537,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.merge", mInstanceId);
+ // Keep all tasks in one list because order matters.
ArrayList<TransitionInfo.Change> openingTasks = null;
+ IntArray openingTaskIsLeafs = null;
ArrayList<TransitionInfo.Change> closingTasks = null;
mOpeningSeparateHome = false;
TransitionInfo.Change recentsOpening = null;
@@ -491,25 +558,29 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
cancel("task #" + taskInfo.taskId + " is always_on_top");
return;
}
- hasTaskChange = hasTaskChange || taskInfo != null;
+ final boolean isRootTask = taskInfo != null
+ && TransitionInfo.isIndependent(change, info);
+ hasTaskChange = hasTaskChange || isRootTask;
final boolean isLeafTask = leafTaskFilter.test(change);
if (TransitionUtil.isOpeningType(change.getMode())) {
if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
recentsOpening = change;
- } else if (isLeafTask) {
- if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ } else if (isRootTask || isLeafTask) {
+ if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
// This is usually a 3p launcher
mOpeningSeparateHome = true;
}
if (openingTasks == null) {
openingTasks = new ArrayList<>();
+ openingTaskIsLeafs = new IntArray();
}
openingTasks.add(change);
+ openingTaskIsLeafs.add(isLeafTask ? 1 : 0);
}
} else if (TransitionUtil.isClosingType(change.getMode())) {
if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
foundRecentsClosing = true;
- } else if (isLeafTask) {
+ } else if (isRootTask || isLeafTask) {
if (closingTasks == null) {
closingTasks = new ArrayList<>();
}
@@ -519,7 +590,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// Finish recents animation if the display is changed, so the default
// transition handler can play the animation such as rotation effect.
if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
- cancel(mWillFinishToHome, "display change");
+ // This call to cancel will use the screenshots taken preemptively in
+ // handleMidTransitionRequest() prior to the display changing
+ cancel(mWillFinishToHome, true /* withScreenshots */, "display change");
return;
}
// Don't consider order-only changes as changing apps.
@@ -573,7 +646,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
}
final TaskState openingTask = mOpeningTasks.remove(openingIdx);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " pausing opening taskId=%d", openingTask.mTaskInfo.taskId);
+ " pausing opening %staskId=%d", openingTask.isLeaf() ? "leaf " : "",
+ openingTask.mTaskInfo.taskId);
mPausingTasks.add(openingTask);
didMergeThings = true;
}
@@ -583,35 +657,55 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// Switching to some new tasks, add to mOpening and remove from mPausing. Also,
// enter NEW_TASK state since this will start the switch-to animation.
final int layer = mInfo.getChanges().size() * 3;
- appearedTargets = new RemoteAnimationTarget[openingTasks.size()];
+ int openingLeafCount = 0;
+ for (int i = 0; i < openingTaskIsLeafs.size(); ++i) {
+ openingLeafCount += openingTaskIsLeafs.get(i);
+ }
+ if (openingLeafCount > 0) {
+ appearedTargets = new RemoteAnimationTarget[openingLeafCount];
+ }
+ int nextTargetIdx = 0;
for (int i = 0; i < openingTasks.size(); ++i) {
final TransitionInfo.Change change = openingTasks.get(i);
+ final boolean isLeaf = openingTaskIsLeafs.get(i) == 1;
int pausingIdx = TaskState.indexOf(mPausingTasks, change);
if (pausingIdx >= 0) {
// Something is showing/opening a previously-pausing app.
- appearedTargets[i] = TransitionUtil.newTarget(
- change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ if (isLeaf) {
+ appearedTargets[nextTargetIdx++] = TransitionUtil.newTarget(
+ change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ }
final TaskState pausingTask = mPausingTasks.remove(pausingIdx);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " opening pausing taskId=%d", pausingTask.mTaskInfo.taskId);
+ " opening pausing %staskId=%d", isLeaf ? "leaf " : "",
+ pausingTask.mTaskInfo.taskId);
mOpeningTasks.add(pausingTask);
// Setup hides opening tasks initially, so make it visible again (since we
// are already showing it).
t.show(change.getLeash());
t.setAlpha(change.getLeash(), 1.f);
- } else {
- // We are receiving new opening tasks, so convert to onTasksAppeared.
- appearedTargets[i] = TransitionUtil.newTarget(
+ } else if (isLeaf) {
+ // We are receiving new opening leaf tasks, so convert to onTasksAppeared.
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(
change, layer, info, t, mLeashMap);
+ appearedTargets[nextTargetIdx++] = target;
// reparent into the original `mInfo` since that's where we are animating.
final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
- t.reparent(appearedTargets[i].leash, mInfo.getRoot(rootIdx).getLeash());
- t.setLayer(appearedTargets[i].leash, layer);
+ t.reparent(target.leash, mInfo.getRoot(rootIdx).getLeash());
+ t.setLayer(target.leash, layer);
// Hide the animation leash, let listener show it.
- t.hide(appearedTargets[i].leash);
+ t.hide(target.leash);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
- " opening new taskId=%d", appearedTargets[i].taskId);
- mOpeningTasks.add(new TaskState(change, appearedTargets[i].leash));
+ " opening new leaf taskId=%d", target.taskId);
+ mOpeningTasks.add(new TaskState(change, target.leash));
+ } else {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ " opening new taskId=%d", change.getTaskInfo().taskId);
+ t.setLayer(change.getLeash(), layer);
+ // Setup hides opening tasks initially, so make it visible since recents
+ // is only animating the leafs.
+ t.show(change.getLeash());
+ mOpeningTasks.add(new TaskState(change, null));
}
}
didMergeThings = true;
@@ -633,7 +727,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
+ foundRecentsClosing);
if (foundRecentsClosing) {
mWillFinishToHome = false;
- cancel(false /* toHome */, "didn't merge");
+ cancel(false /* toHome */, false /* withScreenshots */, "didn't merge");
}
return;
}
@@ -796,7 +890,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
t.show(mOpeningTasks.get(i).mTaskSurface);
}
for (int i = 0; i < mPausingTasks.size(); ++i) {
- if (!sendUserLeaveHint) {
+ if (!sendUserLeaveHint && mPausingTasks.get(i).isLeaf()) {
// This means recents is not *actually* finishing, so of course we gotta
// do special stuff in WMCore to accommodate.
wct.setDoNotPip(mPausingTasks.get(i).mToken);
@@ -875,7 +969,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
/** The surface/leash of the task provided by Core. */
SurfaceControl mTaskSurface;
- /** The (local) animation-leash created for this task. */
+ /** The (local) animation-leash created for this task. Only non-null for leafs. */
+ @Nullable
SurfaceControl mLeash;
TaskState(TransitionInfo.Change change, SurfaceControl leash) {
@@ -894,6 +989,10 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return -1;
}
+ boolean isLeaf() {
+ return mLeash != null;
+ }
+
public String toString() {
return "" + mToken + " : " + mLeash;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 34701f1db7b7..ea33a1f1b56d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -723,7 +723,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
// in the background with priority.
final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
.map(recentTasks -> recentTasks.findTaskInBackground(
- intent.getIntent().getComponent()))
+ intent.getIntent().getComponent(), userId1))
.orElse(null);
if (taskInfo != null) {
startTask(taskInfo.taskId, position, options);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 14ea86a8c0e9..986309948ada 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -87,6 +87,14 @@ class SplitScreenTransitions {
mStageCoordinator = stageCoordinator;
}
+ private void initTransition(@NonNull IBinder transition,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ mAnimatingTransition = transition;
+ mFinishTransaction = finishTransaction;
+ mFinishCallback = finishCallback;
+ }
+
/** Play animation for enter transition or dismiss transition. */
void playAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@@ -94,9 +102,7 @@ class SplitScreenTransitions {
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
@NonNull WindowContainerToken topRoot) {
- mFinishCallback = finishCallback;
- mAnimatingTransition = transition;
- mFinishTransaction = finishTransaction;
+ initTransition(transition, finishTransaction, finishCallback);
final TransitSession pendingTransition = getPendingTransition(transition);
if (pendingTransition != null) {
@@ -220,6 +226,45 @@ class SplitScreenTransitions {
onFinish(null /* wct */, null /* wctCB */);
}
+ /** Play animation for drag divider dismiss transition. */
+ void playDragDismissAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback,
+ @NonNull WindowContainerToken toTopRoot, @NonNull SplitDecorManager toTopDecor,
+ @NonNull WindowContainerToken topRoot) {
+ initTransition(transition, finishTransaction, finishCallback);
+
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final SurfaceControl leash = change.getLeash();
+
+ if (toTopRoot.equals(change.getContainer())) {
+ startTransaction.setAlpha(leash, 1.f);
+ startTransaction.show(leash);
+
+ ValueAnimator va = new ValueAnimator();
+ mAnimations.add(va);
+
+ toTopDecor.onResized(startTransaction, animated -> {
+ mAnimations.remove(va);
+ if (animated) {
+ mTransitions.getMainExecutor().execute(() -> {
+ onFinish(null /* wct */, null /* wctCB */);
+ });
+ }
+ });
+ } else if (topRoot.equals(change.getContainer())) {
+ // Ensure it on top of all changes in transition.
+ startTransaction.setLayer(leash, Integer.MAX_VALUE);
+ startTransaction.setAlpha(leash, 1.f);
+ startTransaction.show(leash);
+ }
+ }
+ startTransaction.apply();
+ onFinish(null /* wct */, null /* wctCB */);
+ }
+
/** Play animation for resize transition. */
void playResizeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@@ -227,9 +272,7 @@ class SplitScreenTransitions {
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
@NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
- mFinishCallback = finishCallback;
- mAnimatingTransition = transition;
- mFinishTransaction = finishTransaction;
+ initTransition(transition, finishTransaction, finishCallback);
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -305,8 +348,6 @@ class SplitScreenTransitions {
WindowContainerTransaction wct,
@Nullable RemoteTransition remoteTransition,
Transitions.TransitionHandler handler,
- @Nullable TransitionConsumedCallback consumedCallback,
- @Nullable TransitionFinishedCallback finishedCallback,
int extraTransitType, boolean resizeAnim) {
if (mPendingEnter != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
@@ -314,20 +355,16 @@ class SplitScreenTransitions {
return null;
}
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
- setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback,
- extraTransitType, resizeAnim);
+ setEnterTransition(transition, remoteTransition, extraTransitType, resizeAnim);
return transition;
}
/** Sets a transition to enter split. */
void setEnterTransition(@NonNull IBinder transition,
@Nullable RemoteTransition remoteTransition,
- @Nullable TransitionConsumedCallback consumedCallback,
- @Nullable TransitionFinishedCallback finishedCallback,
int extraTransitType, boolean resizeAnim) {
mPendingEnter = new EnterSession(
- transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType,
- resizeAnim);
+ transition, remoteTransition, extraTransitType, resizeAnim);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ " deduced Enter split screen");
@@ -565,12 +602,10 @@ class SplitScreenTransitions {
final boolean mResizeAnim;
EnterSession(IBinder transition,
- @Nullable TransitionConsumedCallback consumedCallback,
- @Nullable TransitionFinishedCallback finishedCallback,
@Nullable RemoteTransition remoteTransition,
int extraTransitType, boolean resizeAnim) {
- super(transition, consumedCallback, finishedCallback, remoteTransition,
- extraTransitType);
+ super(transition, null /* consumedCallback */, null /* finishedCallback */,
+ remoteTransition, extraTransitType);
this.mResizeAnim = resizeAnim;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index bf20567834e0..366f4f143374 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
@@ -192,6 +193,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private final SplitScreenTransitions mSplitTransitions;
private final SplitscreenEventLogger mLogger;
private final ShellExecutor mMainExecutor;
+ // Cache live tile tasks while entering recents, evict them from stages in finish transaction
+ // if user is opening another task(s).
+ private final ArrayList<Integer> mPausingTasks = new ArrayList<>();
private final Optional<RecentTasksController> mRecentTasks;
private final Rect mTempRect1 = new Rect();
@@ -393,7 +397,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(wct, task, stagePosition);
if (ENABLE_SHELL_TRANSITIONS) {
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
- null, this, null /* consumedCallback */, null /* finishedCallback */,
+ null, this,
isSplitScreenVisible()
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
!mIsDropEntering);
@@ -504,8 +508,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(wct, null /* taskInfo */, position);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
- null /* consumedCallback */, null /* finishedCallback */, extraTransitType,
- !mIsDropEntering);
+ extraTransitType, !mIsDropEntering);
}
/** Launches an activity into split by legacy transition. */
@@ -658,8 +661,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Add task launch requests
wct.startTask(mainTaskId, mainOptions);
- mSplitTransitions.startEnterTransition(
- TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
+ // leave recents animation by re-start pausing tasks
+ if (mPausingTasks.contains(mainTaskId)) {
+ mPausingTasks.clear();
+ }
+ mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, remoteTransition, this,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
setEnterInstanceId(instanceId);
}
@@ -709,8 +715,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
wct.sendPendingIntent(pendingIntent2, fillInIntent2, options2);
}
- mSplitTransitions.startEnterTransition(
- TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
+ mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, remoteTransition, this,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
setEnterInstanceId(instanceId);
}
@@ -1328,8 +1333,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mIsExiting = true;
childrenToTop.resetBounds(wct);
wct.reorder(childrenToTop.mRootTaskInfo.token, true);
- wct.setSmallestScreenWidthDp(childrenToTop.mRootTaskInfo.token,
- SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
}
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
false /* reparentLeafTaskIfRelaunch */);
@@ -1448,8 +1451,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!mMainStage.isActive()) return;
mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
- wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
- false /* reparentLeafTaskIfRelaunch */);
}
private void prepareEnterSplitScreen(WindowContainerTransaction wct) {
@@ -1517,6 +1518,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
void finishEnterSplitScreen(SurfaceControl.Transaction t) {
mSplitLayout.update(t);
+ mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash,
+ getMainStageBounds());
+ mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash,
+ getSideStageBounds());
setDividerVisibility(true, t);
// Ensure divider surface are re-parented back into the hierarchy at the end of the
// transition. See Transition#buildFinishTransaction for more detail.
@@ -1628,7 +1633,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
private void updateRecentTasksSplitPair() {
- if (!mShouldUpdateRecents) {
+ // Preventing from single task update while processing recents.
+ if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) {
return;
}
mRecentTasks.ifPresent(recentTasks -> {
@@ -1989,13 +1995,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final boolean mainStageToTop =
bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
+ final StageTaskListener toTopStage = mainStageToTop ? mMainStage : mSideStage;
if (!ENABLE_SHELL_TRANSITIONS) {
- exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason);
+ exitSplitScreen(toTopStage, reason);
return;
}
final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
final WindowContainerTransaction wct = new WindowContainerTransaction();
+ toTopStage.resetBounds(wct);
prepareExitSplitScreen(dismissTop, wct);
if (mRootTaskInfo != null) {
wct.setDoNotPip(mRootTaskInfo.token);
@@ -2283,14 +2291,28 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
out = new WindowContainerTransaction();
final StageTaskListener stage = getStageOfTask(triggerTask);
if (stage != null) {
- // Dismiss split if the last task in one of the stages is going away
if (isClosingType(type) && stage.getChildCount() == 1) {
+ // Dismiss split if the last task in one of the stages is going away
// The top should be the opposite side that is closing:
- int dismissTop = getStageType(stage) == STAGE_TYPE_MAIN ? STAGE_TYPE_SIDE
- : STAGE_TYPE_MAIN;
+ int dismissTop = getStageType(stage) == STAGE_TYPE_MAIN
+ ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
prepareExitSplitScreen(dismissTop, out);
mSplitTransitions.setDismissTransition(transition, dismissTop,
EXIT_REASON_APP_FINISHED);
+ } else if (isOpening && !mPausingTasks.isEmpty()) {
+ // One of the splitting task is opening while animating the split pair in
+ // recents, which means to dismiss the split pair to this task.
+ int dismissTop = getStageType(stage) == STAGE_TYPE_MAIN
+ ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ prepareExitSplitScreen(dismissTop, out);
+ mSplitTransitions.setDismissTransition(transition, dismissTop,
+ EXIT_REASON_APP_FINISHED);
+ } else if (!isSplitScreenVisible() && isOpening) {
+ // If split running backgroud and trigger task is appearing into split,
+ // prepare to enter split screen.
+ prepareEnterSplitScreen(out);
+ mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
}
} else if (isOpening && inFullscreen) {
final int activityType = triggerTask.getActivityType();
@@ -2315,8 +2337,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
out = new WindowContainerTransaction();
prepareEnterSplitScreen(out);
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
- null /* consumedCallback */, null /* finishedCallback */,
- TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, !mIsDropEntering);
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
}
}
return out;
@@ -2386,6 +2407,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (change.getMode() == TRANSIT_CHANGE
&& (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
mSplitLayout.update(startTransaction);
+ record.mContainDisplayChange = true;
}
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
@@ -2415,7 +2437,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
continue;
}
final StageTaskListener stage = getStageOfTask(taskInfo);
- if (stage == null) continue;
+ if (stage == null) {
+ if (change.getParent() == null && !isClosingType(change.getMode())
+ && taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
+ record.mContainShowPipChange = true;
+ }
+ continue;
+ }
if (isOpeningType(change.getMode())) {
if (!stage.containsTask(taskInfo.taskId)) {
Log.w(TAG, "Expected onTaskAppeared on " + stage + " to have been called"
@@ -2430,13 +2458,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
}
- // If the size of dismissStages == 1, one of the task is closed without prepare pending
- // transition, which could happen if all activities were finished after finish top
- // activity in a task, so the trigger task is null when handleRequest.
- // Note if the size of dismissStages == 2, it's starting a new task, so don't handle it.
final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
+ if (!record.mContainDisplayChange && record.mContainShowPipChange) {
+ // This occurred when split enter pip by open another fullscreen app so let
+ // pip tranistion handler to handle this but also start our dismiss transition.
+ // TODO(b/282894249): Should improve this case animation on pip.
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
+ mSplitTransitions.startDismissTransition(wct, this, STAGE_TYPE_UNDEFINED,
+ EXIT_REASON_CHILD_TASK_ENTER_PIP);
+ } else if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
|| dismissStages.size() == 1) {
+ // If the size of dismissStages == 1, one of the task is closed without prepare
+ // pending transition, which could happen if all activities were finished after
+ // finish top activity in a task, so the trigger task is null when handleRequest.
+ // Note if the size of dismissStages == 2, it's starting a new task,
+ // so don't handle it.
Log.e(TAG, "Somehow removed the last task in a stage outside of a proper "
+ "transition.");
final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -2453,7 +2490,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// TODO(b/184679596): Find a way to either include task-org information in
// the transition, or synchronize task-org callbacks.
}
-
// Use normal animations.
return false;
} else if (mMixedHandler != null && TransitionUtil.hasDisplayChange(info)) {
@@ -2470,6 +2506,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
static class StageChangeRecord {
+ boolean mContainDisplayChange = false;
+ boolean mContainShowPipChange = false;
static class StageChange {
final StageTaskListener mStageTaskListener;
final IntArray mAddedTaskId = new IntArray();
@@ -2531,8 +2569,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
shouldAnimate = startPendingEnterAnimation(
mSplitTransitions.mPendingEnter, info, startTransaction, finishTransaction);
} else if (mSplitTransitions.isPendingDismiss(transition)) {
+ final SplitScreenTransitions.DismissSession dismiss = mSplitTransitions.mPendingDismiss;
shouldAnimate = startPendingDismissAnimation(
- mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
+ dismiss, info, startTransaction, finishTransaction);
+ if (shouldAnimate && dismiss.mReason == EXIT_REASON_DRAG_DIVIDER) {
+ final StageTaskListener toTopStage =
+ dismiss.mDismissTop == STAGE_TYPE_MAIN ? mMainStage : mSideStage;
+ mSplitTransitions.playDragDismissAnimation(transition, info, startTransaction,
+ finishTransaction, finishCallback, toTopStage.mRootTaskInfo.token,
+ toTopStage.getSplitDecorManager(), mRootTaskInfo.token);
+ return true;
+ }
} else if (mSplitTransitions.isPendingResize(transition)) {
mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
@@ -2565,17 +2612,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// First, verify that we actually have opened apps in both splits.
TransitionInfo.Change mainChild = null;
TransitionInfo.Change sideChild = null;
+ final WindowContainerTransaction evictWct = new WindowContainerTransaction();
for (int iC = 0; iC < info.getChanges().size(); ++iC) {
final TransitionInfo.Change change = info.getChanges().get(iC);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+ if (mPausingTasks.contains(taskInfo.taskId)) {
+ continue;
+ }
final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
- if (stageType == STAGE_TYPE_MAIN
+ if (mainChild == null && stageType == STAGE_TYPE_MAIN
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
// Includes TRANSIT_CHANGE to cover reparenting top-most task to split.
mainChild = change;
- } else if (stageType == STAGE_TYPE_SIDE && isOpeningType(change.getMode())) {
+ } else if (sideChild == null && stageType == STAGE_TYPE_SIDE
+ && isOpeningType(change.getMode())) {
sideChild = change;
+ } else if (stageType != STAGE_TYPE_UNDEFINED && change.getMode() == TRANSIT_TO_BACK) {
+ // Collect all to back task's and evict them when transition finished.
+ evictWct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
}
}
@@ -2585,6 +2640,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
Log.w(TAG, "Launched a task in split, but didn't receive any task in transition.");
mSplitTransitions.mPendingEnter.cancel((cancelWct, cancelT)
-> prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, cancelWct));
+ mSplitUnsupportedToast.show();
return true;
}
} else {
@@ -2595,6 +2651,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
(sideChild != null ? STAGE_TYPE_SIDE : STAGE_TYPE_UNDEFINED);
mSplitTransitions.mPendingEnter.cancel(
(cancelWct, cancelT) -> prepareExitSplitScreen(dismissTop, cancelWct));
+ mSplitUnsupportedToast.show();
return true;
}
}
@@ -2637,10 +2694,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSideStage.evictInvisibleChildren(callbackWct);
}
}
+ if (!evictWct.isEmpty()) {
+ callbackWct.merge(evictWct, true);
+ }
if (enterTransition.mResizeAnim) {
mShowDecorImmediately = true;
mSplitLayout.flingDividerToCenter();
}
+ callbackWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, false);
+ mPausingTasks.clear();
});
finishEnterSplitScreen(finishT);
@@ -2787,6 +2849,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.mPendingDismiss = null;
return false;
}
+ dismissTransition.setFinishedCallback((callbackWct, callbackT) -> {
+ mMainStage.getSplitDecorManager().release(callbackT);
+ mSideStage.getSplitDecorManager().release(callbackT);
+ callbackWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, false);
+ });
addDividerBarToTransition(info, false /* show */);
return true;
@@ -2794,12 +2861,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
/** Call this when starting the open-recents animation while split-screen is active. */
public void onRecentsInSplitAnimationStart(TransitionInfo info) {
+ if (isSplitScreenVisible()) {
+ // Cache tasks on live tile.
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (TransitionUtil.isClosingType(change.getMode())
+ && change.getTaskInfo() != null) {
+ final int taskId = change.getTaskInfo().taskId;
+ if (mMainStage.getTopVisibleChildTaskId() == taskId
+ || mSideStage.getTopVisibleChildTaskId() == taskId) {
+ mPausingTasks.add(taskId);
+ }
+ }
+ }
+ }
+
addDividerBarToTransition(info, false /* show */);
}
+ /** Call this when the recents animation canceled during split-screen. */
+ public void onRecentsInSplitAnimationCanceled() {
+ mPausingTasks.clear();
+ }
+
/** Call this when the recents animation during split-screen finishes. */
public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
- SurfaceControl.Transaction finishT, TransitionInfo info) {
+ SurfaceControl.Transaction finishT) {
+ mPausingTasks.clear();
// Check if the recent transition is finished by returning to the current
// split, so we can restore the divider bar.
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
@@ -2818,11 +2906,31 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
setSplitsVisible(false);
- finishWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
- true /* reparentLeafTaskIfRelaunch */);
+ prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
logExit(EXIT_REASON_UNKNOWN);
}
+ /** Call this when the recents animation finishes by doing pair-to-pair switch. */
+ public void onRecentsPairToPairAnimationFinish(WindowContainerTransaction finishWct) {
+ // Pair-to-pair switch happened so here should evict the live tile from its stage.
+ // Otherwise, the task will remain in stage, and occluding the new task when next time
+ // user entering recents.
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ final int taskId = mPausingTasks.get(i);
+ if (mMainStage.containsTask(taskId)) {
+ mMainStage.evictChildren(finishWct, taskId);
+ } else if (mSideStage.containsTask(taskId)) {
+ mSideStage.evictChildren(finishWct, taskId);
+ }
+ }
+ // If pending enter hasn't consumed, the mix handler will invoke start pending
+ // animation within following transition.
+ if (mSplitTransitions.mPendingEnter == null) {
+ mPausingTasks.clear();
+ updateRecentTasksSplitPair();
+ }
+ }
+
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
final SurfaceControl leash = mSplitLayout.getDividerLeash();
if (leash == null || !leash.isValid()) {
@@ -2875,6 +2983,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
pw.println(innerPrefix + "SplitLayout");
mSplitLayout.dump(pw, childPrefix);
}
+ if (!mPausingTasks.isEmpty()) {
+ pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index e2e9270cd6cc..92ff5fed4584 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
@@ -201,7 +202,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
if (mRootTaskInfo.taskId == taskInfo.taskId) {
// Inflates split decor view only when the root task is visible.
- if (mRootTaskInfo.isVisible != taskInfo.isVisible) {
+ if (!ENABLE_SHELL_TRANSITIONS && mRootTaskInfo.isVisible != taskInfo.isVisible) {
if (taskInfo.isVisible) {
mSplitDecorManager.inflate(mContext, mRootLeash,
taskInfo.configuration.windowConfiguration.getBounds());
@@ -376,6 +377,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
}
+ void evictChildren(WindowContainerTransaction wct, int taskId) {
+ final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.get(taskId);
+ if (taskInfo != null) {
+ wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
+ }
+ }
+
void reparentTopTask(WindowContainerTransaction wct) {
wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
@@ -385,6 +393,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
void resetBounds(WindowContainerTransaction wct) {
wct.setBounds(mRootTaskInfo.token, null);
wct.setAppBounds(mRootTaskInfo.token, null);
+ wct.setSmallestScreenWidthDp(mRootTaskInfo.token, SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
}
void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 863b5ab73a7d..5ee5324f8758 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -40,6 +40,9 @@ import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransactionCallback;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.desktopmode.DesktopModeController;
+import com.android.wm.shell.desktopmode.DesktopModeStatus;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
@@ -65,6 +68,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
private RecentsTransitionHandler mRecentsHandler;
private StageCoordinator mSplitHandler;
private final KeyguardTransitionHandler mKeyguardHandler;
+ private DesktopModeController mDesktopModeController;
+ private DesktopTasksController mDesktopTasksController;
private static class MixedTransition {
static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
@@ -81,6 +86,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
/** Keyguard exit/occlude/unocclude transition. */
static final int TYPE_KEYGUARD = 5;
+ /** Recents Transition while in desktop mode. */
+ static final int TYPE_RECENTS_DURING_DESKTOP = 6;
+
/** The default animation for this mixed transition. */
static final int ANIM_TYPE_DEFAULT = 0;
@@ -132,7 +140,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
Optional<SplitScreenController> splitScreenControllerOptional,
Optional<PipTouchHandler> pipTouchHandlerOptional,
Optional<RecentsTransitionHandler> recentsHandlerOptional,
- KeyguardTransitionHandler keyguardHandler) {
+ KeyguardTransitionHandler keyguardHandler,
+ Optional<DesktopModeController> desktopModeControllerOptional,
+ Optional<DesktopTasksController> desktopTasksControllerOptional) {
mPlayer = player;
mKeyguardHandler = keyguardHandler;
if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
@@ -149,6 +159,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
if (mRecentsHandler != null) {
mRecentsHandler.addMixer(this);
}
+ mDesktopModeController = desktopModeControllerOptional.orElse(null);
+ mDesktopTasksController = desktopTasksControllerOptional.orElse(null);
}, this);
}
}
@@ -218,7 +230,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
@Override
public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
- if (mRecentsHandler != null && mSplitHandler.isSplitScreenVisible()) {
+ if (mRecentsHandler != null && (mSplitHandler.isSplitScreenVisible()
+ || DesktopModeStatus.isActive(mPlayer.getContext()))) {
return this;
}
return null;
@@ -233,6 +246,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
mixed.mLeftoversHandler = mRecentsHandler;
mActiveTransitions.add(mixed);
+ } else if (DesktopModeStatus.isActive(mPlayer.getContext())) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
+ + "desktop mode is active, so treat it as Mixed.");
+ final MixedTransition mixed = new MixedTransition(
+ MixedTransition.TYPE_RECENTS_DURING_DESKTOP, transition);
+ mixed.mLeftoversHandler = mRecentsHandler;
+ mActiveTransitions.add(mixed);
} else {
throw new IllegalStateException("Accepted a recents transition but don't know how to"
+ " handle it");
@@ -306,6 +326,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
return animateKeyguard(mixed, info, startTransaction, finishTransaction,
finishCallback);
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) {
+ return animateRecentsDuringDesktop(mixed, info, startTransaction, finishTransaction,
+ finishCallback);
} else {
mActiveTransitions.remove(mixed);
throw new IllegalStateException("Starting mixed animation without a known mixed type? "
@@ -540,9 +563,12 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
mixed.mInFlightSubAnimations = 0;
mActiveTransitions.remove(mixed);
// If pair-to-pair switching, the post-recents clean-up isn't needed.
+ wct = wct != null ? wct : new WindowContainerTransaction();
if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
- wct = wct != null ? wct : new WindowContainerTransaction();
- mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
+ mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
+ } else {
+ // notify pair-to-pair recents animation finish
+ mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
}
mSplitHandler.onTransitionAnimationComplete();
finishCallback.onTransitionFinished(wct, wctCB);
@@ -552,6 +578,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
startTransaction, finishTransaction, finishCB);
if (!handled) {
+ mSplitHandler.onRecentsInSplitAnimationCanceled();
mActiveTransitions.remove(mixed);
}
return handled;
@@ -578,6 +605,30 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
return true;
}
+ private boolean animateRecentsDuringDesktop(@NonNull final MixedTransition mixed,
+ @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ boolean consumed = mRecentsHandler.startAnimation(
+ mixed.mTransition, info, startTransaction, finishTransaction, finishCallback);
+ if (!consumed) {
+ return false;
+ }
+ //Sync desktop mode state (proto 1)
+ if (mDesktopModeController != null) {
+ mDesktopModeController.syncSurfaceState(info, finishTransaction);
+ return true;
+ }
+ //Sync desktop mode state (proto 2)
+ if (mDesktopTasksController != null) {
+ mDesktopTasksController.syncSurfaceState(info, finishTransaction);
+ return true;
+ }
+
+ return false;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -621,6 +672,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
finishCallback);
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
mKeyguardHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) {
+ mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
+ finishCallback);
} else {
throw new IllegalStateException("Playing a mixed transition with unknown type? "
+ mixed.mType);
@@ -646,6 +700,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
} else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
mKeyguardHandler.onTransitionConsumed(transition, aborted, finishT);
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) {
+ mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 6a2468a7eaa2..4c678a2bf29b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -299,7 +299,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
// Early check if the transition doesn't warrant an animation.
- if (Transitions.isAllNoAnimation(info) || Transitions.isAllOrderOnly(info)) {
+ if (Transitions.isAllNoAnimation(info) || Transitions.isAllOrderOnly(info)
+ || (info.getFlags() & WindowManager.TRANSIT_FLAG_INVISIBLE) != 0) {
startTransaction.apply();
finishTransaction.apply();
finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
@@ -326,6 +327,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final int wallpaperTransit = getWallpaperTransitType(info);
boolean isDisplayRotationAnimationStarted = false;
final boolean isDreamTransition = isDreamTransition(info);
+ final boolean isOnlyTranslucent = isOnlyTranslucent(info);
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -451,6 +453,17 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final int layer = zSplitLine + numChanges - i;
startTransaction.setLayer(change.getLeash(), layer);
}
+ } else if (isOnlyTranslucent && TransitionUtil.isOpeningType(info.getType())
+ && TransitionUtil.isClosingType(mode)) {
+ // If there is a closing translucent task in an OPENING transition, we will
+ // actually select a CLOSING animation, so move the closing task into
+ // the animating part of the z-order.
+
+ // See Transitions#setupAnimHierarchy for details about these variables.
+ final int numChanges = info.getChanges().size();
+ final int zSplitLine = numChanges + 1;
+ final int layer = zSplitLine + numChanges - i;
+ startTransaction.setLayer(change.getLeash(), layer);
}
}
@@ -542,6 +555,29 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return false;
}
+ /**
+ * Does `info` only contain translucent visibility changes (CHANGEs are ignored). We select
+ * different animations and z-orders for these
+ */
+ private static boolean isOnlyTranslucent(@NonNull TransitionInfo info) {
+ int translucentOpen = 0;
+ int translucentClose = 0;
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.getMode() == TRANSIT_CHANGE) continue;
+ if (change.hasFlags(FLAG_TRANSLUCENT)) {
+ if (TransitionUtil.isOpeningType(change.getMode())) {
+ translucentOpen += 1;
+ } else {
+ translucentClose += 1;
+ }
+ } else {
+ return false;
+ }
+ }
+ return (translucentOpen + translucentClose) > 0;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index 19d8384ace41..d978eafa97f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -23,6 +23,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -102,10 +103,11 @@ public class TransitionAnimationHelper {
// We will translucent open animation for translucent activities and tasks. Choose
// WindowAnimation_activityOpenEnterAnimation and set translucent here, then
// TransitionAnimation loads appropriate animation later.
- if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
- translucent = true;
- }
- if (isTask && !translucent) {
+ translucent = (changeFlags & FLAG_TRANSLUCENT) != 0;
+ if (isTask && translucent && !enter) {
+ // For closing translucent tasks, use the activity close animation
+ animAttr = R.styleable.WindowAnimation_activityCloseExitAnimation;
+ } else if (isTask && !translucent) {
animAttr = enter
? R.styleable.WindowAnimation_taskOpenEnterAnimation
: R.styleable.WindowAnimation_taskOpenExitAnimation;
@@ -150,6 +152,10 @@ public class TransitionAnimationHelper {
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
animAttr, translucent);
}
+ } else if (translucent && !isTask && ((changeFlags & FLAGS_IS_NON_APP_WINDOW) == 0)) {
+ // Un-styled translucent activities technically have undefined animations; however,
+ // as is always the case, some apps now rely on this being no-animation, so skip
+ // loading animations here.
} else {
a = transitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index d16b497b5aca..de20c2d90066 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -16,9 +16,12 @@
package com.android.wm.shell.transition;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -26,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
@@ -191,6 +195,12 @@ public class Transitions implements RemoteCallable<Transitions>,
*/
private static final int SYNC_ALLOWANCE_MS = 120;
+ /**
+ * Keyguard gets a more generous timeout to finish its animations, because we are always holding
+ * a sleep token during occlude/unocclude transitions and we want them to finish playing cleanly
+ */
+ private static final int SYNC_ALLOWANCE_KEYGUARD_MS = 2000;
+
/** For testing only. Disables the force-finish timeout on sync. */
private boolean mDisableForceSync = false;
@@ -545,7 +555,10 @@ public class Transitions implements RemoteCallable<Transitions>,
layer = -zSplitLine - i;
}
} else if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
- if (isOpening) {
+ if (isOpening
+ // This is for when an activity launches while a different transition is
+ // collecting.
+ || change.hasFlags(FLAG_MOVED_TO_TOP)) {
// put on top
layer = zSplitLine + numChanges - i;
} else {
@@ -561,8 +574,8 @@ public class Transitions implements RemoteCallable<Transitions>,
layer = zSplitLine + numChanges - i;
}
} else { // CHANGE or other
- if (isClosing) {
- // Put below CLOSE mode.
+ if (isClosing || TransitionUtil.isOrderOnly(change)) {
+ // Put below CLOSE mode (in the "static" section).
layer = zSplitLine - i;
} else {
// Put above CLOSE mode.
@@ -673,7 +686,7 @@ public class Transitions implements RemoteCallable<Transitions>,
// Sleep starts a process of forcing all prior transitions to finish immediately
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
"Start finish-for-sync track %d", i);
- finishForSync(i, null /* forceFinish */);
+ finishForSync(active, i, null /* forceFinish */);
}
if (hadPreceding) {
return false;
@@ -1021,6 +1034,9 @@ public class Transitions implements RemoteCallable<Transitions>,
for (int i = 0; i < mPendingTransitions.size(); ++i) {
if (mPendingTransitions.get(i).mToken == token) return true;
}
+ for (int i = 0; i < mReadyDuringSync.size(); ++i) {
+ if (mReadyDuringSync.get(i).mToken == token) return true;
+ }
for (int t = 0; t < mTracks.size(); ++t) {
final Track tr = mTracks.get(t);
for (int i = 0; i < tr.mReadyTransitions.size(); ++i) {
@@ -1072,6 +1088,16 @@ public class Transitions implements RemoteCallable<Transitions>,
}
}
}
+ if (request.getType() == TRANSIT_KEYGUARD_OCCLUDE && request.getTriggerTask() != null
+ && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ // This freeform task is on top of keyguard, so its windowing mode should be changed to
+ // fullscreen.
+ if (wct == null) {
+ wct = new WindowContainerTransaction();
+ }
+ wct.setWindowingMode(request.getTriggerTask().token, WINDOWING_MODE_FULLSCREEN);
+ wct.setBounds(request.getTriggerTask().token, null);
+ }
mOrganizer.startTransition(transitionToken, wct != null && wct.isEmpty() ? null : wct);
active.mToken = transitionToken;
// Currently, WMCore only does one transition at a time. If it makes a requestStart, it
@@ -1107,10 +1133,17 @@ public class Transitions implements RemoteCallable<Transitions>,
*
* This is then repeated until there are no more pending sleep transitions.
*
+ * @param reason The SLEEP transition that triggered this round of finishes. We will continue
+ * looping round finishing transitions as long as this is still waiting.
* @param forceFinish When non-null, this is the transition that we last sent the SLEEP merge
* signal to -- so it will be force-finished if it's still running.
*/
- private void finishForSync(int trackIdx, @Nullable ActiveTransition forceFinish) {
+ private void finishForSync(ActiveTransition reason,
+ int trackIdx, @Nullable ActiveTransition forceFinish) {
+ if (!isTransitionKnown(reason.mToken)) {
+ Log.d(TAG, "finishForSleep: already played sync transition " + reason);
+ return;
+ }
final Track track = mTracks.get(trackIdx);
if (forceFinish != null) {
final Track trk = mTracks.get(forceFinish.getTrack());
@@ -1154,8 +1187,11 @@ public class Transitions implements RemoteCallable<Transitions>,
if (track.mActiveTransition == playing) {
if (!mDisableForceSync) {
// Give it a short amount of time to process it before forcing.
- mMainExecutor.executeDelayed(() -> finishForSync(trackIdx, playing),
- SYNC_ALLOWANCE_MS);
+ final int tolerance = KeyguardTransitionHandler.handles(playing.mInfo)
+ ? SYNC_ALLOWANCE_KEYGUARD_MS
+ : SYNC_ALLOWANCE_MS;
+ mMainExecutor.executeDelayed(
+ () -> finishForSync(reason, trackIdx, playing), tolerance);
}
break;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index bb0eba6a0fc7..c504f57216f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -173,6 +173,17 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
mTransition = null;
}
+ @Override
+ public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+ @NonNull TransitionFinishCallback finishCallback) {
+ if (info.getType() == TRANSIT_CHANGE) {
+ // Apply changes happening during the unfold animation immediately
+ t.apply();
+ finishCallback.onTransitionFinished(null, null);
+ }
+ }
+
@Nullable
@Override
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
index f81fc6fbea49..6bba0d1386fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
@@ -110,7 +110,7 @@ public class FullscreenUnfoldTaskAnimator implements UnfoldTaskAnimator,
for (int i = state.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = state.sourceAt(i);
if (source.getType() == WindowInsets.Type.navigationBars()
- && source.insetsRoundedCornerFrame()) {
+ && source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
return source;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
index a4cf149cc3b5..21994a997be5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
@@ -50,11 +50,11 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.unfold.UnfoldAnimationController;
import com.android.wm.shell.unfold.UnfoldBackgroundController;
+import dagger.Lazy;
+
import java.util.Optional;
import java.util.concurrent.Executor;
-import dagger.Lazy;
-
/**
* This helper class contains logic that calculates scaling and cropping parameters
* for the folding/unfolding animation. As an input it receives TaskInfo objects and
@@ -149,7 +149,7 @@ public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
for (int i = state.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = state.sourceAt(i);
if (source.getType() == WindowInsets.Type.navigationBars()
- && source.insetsRoundedCornerFrame()) {
+ && source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
return source;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index 143b42a1ec96..c33a633f2068 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -121,15 +121,14 @@ public class TransitionUtil {
@Override
public boolean test(TransitionInfo.Change change) {
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo == null) return false;
// Children always come before parent since changes are in top-to-bottom z-order.
- if ((taskInfo == null) || mChildTaskTargets.get(taskInfo.taskId)) {
- // has children, so not a leaf. Skip.
- return false;
- }
+ boolean hasChildren = mChildTaskTargets.get(taskInfo.taskId);
if (taskInfo.hasParentTask()) {
mChildTaskTargets.put(taskInfo.parentTaskId, true);
}
- return true;
+ // If it has children, it's not a leaf.
+ return !hasChildren;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 15abbf298b24..2fd34d9dc699 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -411,7 +411,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
- position));
+ position, e.getRawY()));
final boolean wasDragging = mIsDragging;
mIsDragging = false;
return wasDragging;
@@ -820,8 +820,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
@NonNull DesktopModeWindowDecoration windowDecoration,
@NonNull RunningTaskInfo taskInfo) {
final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width();
- final Rect disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
- getStatusBarHeight(taskInfo.displayId));
+ final Rect disallowedAreaForEndBounds;
+ if (DesktopModeStatus.isProto2Enabled()) {
+ disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
+ getStatusBarHeight(taskInfo.displayId));
+ } else {
+ disallowedAreaForEndBounds = null;
+ }
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
mDisplayController, disallowedAreaForEndBounds, mDragStartListener,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index 58c78e6a5b9f..39b90218dce1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -55,7 +55,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
private final Rect mRepositionTaskBounds = new Rect();
// If a task move (not resize) finishes in this region, the positioner will not attempt to
// finalize the bounds there using WCT#setBounds
- private final Rect mDisallowedAreaForEndBounds = new Rect();
+ private final Rect mDisallowedAreaForEndBounds;
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
private int mCtrlType;
@@ -77,7 +77,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
mDesktopWindowDecoration = windowDecoration;
mDisplayController = displayController;
mDragStartListener = dragStartListener;
- mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds);
+ mDisallowedAreaForEndBounds = new Rect(disallowedAreaForEndBounds);
mTransactionSupplier = supplier;
mTransitions = transitions;
}
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 ac5ff2075901..67ec6cf4304e 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
@@ -248,6 +248,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight + params.mCaptionY;
wct.addInsetsSource(mTaskInfo.token,
mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect);
+ wct.addInsetsSource(mTaskInfo.token,
+ mOwner, 0 /* index */, WindowInsets.Type.mandatorySystemGestures(),
+ mCaptionInsetsRect);
} else {
startT.hide(mCaptionContainerSurface);
}
@@ -345,6 +348,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get();
wct.removeInsetsSource(mTaskInfo.token,
mOwner, 0 /* index */, WindowInsets.Type.captionBar());
+ wct.removeInsetsSource(mTaskInfo.token,
+ mOwner, 0 /* index */, WindowInsets.Type.mandatorySystemGestures());
mTaskOrganizer.applyTransaction(wct);
}
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index 78a2a38ee3af..e382a0f0aeda 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -70,6 +70,7 @@ java_defaults {
],
data: [
":FlickerTestApp",
+ "trace_config/*",
],
}
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
index 8818aa205266..991d7b5480c4 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
@@ -15,51 +15,85 @@
~ limitations under the License.
-->
<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
- <option name="test-tag" value="FlickerTests" />
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<!-- keeps the screen on during tests -->
- <option name="screen-always-on" value="on" />
+ <option name="screen-always-on" value="on"/>
<!-- prevents the phone from restarting -->
- <option name="force-skip-system-props" value="true" />
+ <option name="force-skip-system-props" value="true"/>
<!-- set WM tracing verbose level to all -->
- <option name="run-command" value="cmd window tracing level all" />
+ <option name="run-command" value="cmd window tracing level all"/>
<!-- set WM tracing to frame (avoid incomplete states) -->
- <option name="run-command" value="cmd window tracing frame" />
+ <option name="run-command" value="cmd window tracing frame"/>
<!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
- <option name="run-command" value="pm disable com.google.android.internal.betterbug" />
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
<!-- ensure lock screen mode is swipe -->
- <option name="run-command" value="locksettings set-disabled false" />
+ <option name="run-command" value="locksettings set-disabled false"/>
<!-- restart launcher to activate TAPL -->
- <option name="run-command" value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher" />
- <!-- Ensure output directory is empty at the start -->
- <option name="run-command" value="rm -rf /sdcard/flicker" />
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
<!-- Increase trace size: 20mb for WM and 80mb for SF -->
- <option name="run-command" value="cmd window tracing size 20480" />
- <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920" />
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1" />
- <option name="run-command" value="settings put system show_touches 1" />
- <option name="run-command" value="settings put system pointer_location 1" />
- <option name="teardown-command" value="settings delete secure show_ime_with_hard_keyboard" />
- <option name="teardown-command" value="settings delete system show_touches" />
- <option name="teardown-command" value="settings delete system pointer_location" />
- <option name="teardown-command" value="cmd overlay enable com.android.internal.systemui.navbar.gestural" />
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
<option name="test-file-name" value="{MODULE}.apk"/>
- <option name="test-file-name" value="FlickerTestApp.apk" />
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="{PACKAGE}"/>
- <option name="shell-timeout" value="6600s" />
- <option name="test-timeout" value="6000s" />
- <option name="hidden-api-checks" value="false" />
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
</test>
+ <!-- Needed for pulling the collected trace config on to the host -->
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
- <option name="directory-keys" value="/sdcard/flicker" />
- <option name="collect-on-run-ended-only" value="true" />
- <option name="clean-up" value="true" />
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.splitscreen/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
</metrics_collector>
</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index b7e73ad11c9f..72f25f36c9d9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.traces.component.EdgeExtensionComponentMatcher
@@ -60,6 +61,7 @@ class CopyContentInSplit(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 0b0a3dad320b..ed3df9ced3b0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -58,6 +59,7 @@ class DragDividerToResize(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index 8cf871f88314..b4c6afd14a90 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
@@ -59,6 +60,7 @@ class SwitchAppByDoubleTapDivider(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
index 3b2da8dbcf9f..2cedc3570cfd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -62,6 +63,7 @@ class SwitchBetweenSplitPairs(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
new file mode 100644
index 000000000000..676c150815ad
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.common.NavBar
+import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
+import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
+import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
+import com.android.wm.shell.flicker.layerIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitscreen.benchmark.UnlockKeyguardToSplitScreenBenchmark
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test unlocking insecure keyguard to back to split screen tasks and verify the transition behavior.
+ *
+ * To run this test: `atest WMShellFlickerTests:UnlockKeyguardToSplitScreen`
+ */
+@RequiresDevice
+@Postsubmit
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class UnlockKeyguardToSplitScreen(override val flicker: FlickerTest) :
+ UnlockKeyguardToSplitScreenBenchmark(flicker), ICommonAssertions {
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit
+ get() = {
+ defaultSetup(this)
+ defaultTeardown(this)
+ thisTransition(this)
+ }
+
+ @Test
+ fun splitScreenDividerIsVisibleAtEnd() {
+ flicker.assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
+ }
+
+ @Test fun primaryAppLayerIsVisibleAtEnd() = flicker.layerIsVisibleAtEnd(primaryApp)
+
+ @Test
+ fun primaryAppBoundsIsVisibleAtEnd() =
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ primaryApp,
+ landscapePosLeft = false,
+ portraitPosTop = false
+ )
+
+ @Test
+ fun secondaryAppBoundsIsVisibleAtEnd() =
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ secondaryApp,
+ landscapePosLeft = true,
+ portraitPosTop = true
+ )
+
+ @Test
+ fun primaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(primaryApp)
+
+ @Test
+ fun secondaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(secondaryApp)
+
+ @Test
+ fun notOverlapsForPrimaryAndSecondaryAppLayers() {
+ flicker.assertLayers {
+ this.invoke("notOverlapsForPrimaryAndSecondaryLayers") {
+ val primaryAppRegions = it.subjects.filter { subject ->
+ subject.name.contains(primaryApp.toLayerName()) && subject.isVisible
+ }.mapNotNull { primaryApp -> primaryApp.layer.visibleRegion }.toTypedArray()
+
+ val primaryAppRegionArea = RegionSubject(primaryAppRegions, it.timestamp)
+ it.visibleRegion(secondaryApp).notOverlaps(primaryAppRegionArea.region)
+ }
+ }
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): List<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
index a189a3f67eca..a5ad97d8ad65 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -62,6 +63,7 @@ open class CopyContentInSplitBenchmark(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
index 55ab7b3a30e4..fa6a4bfbcda6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -68,6 +69,7 @@ open class DismissSplitScreenByDividerBenchmark(flicker: FlickerTest) : SplitScr
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
index c4cfd1add25c..d2beb678a4d5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -55,6 +56,7 @@ open class DismissSplitScreenByGoHomeBenchmark(override val flicker: FlickerTest
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
index 146287c21c75..e95fd947ebde 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -58,6 +59,7 @@ open class DragDividerToResizeBenchmark(override val flicker: FlickerTest) :
Assume.assumeTrue(tapl.isTablet || !flicker.scenario.isLandscapeOrSeascapeAtStart)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
index cc715021adf4..63b74e29c39c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -70,6 +71,7 @@ open class EnterSplitScreenByDragFromAllAppsBenchmark(override val flicker: Flic
Assume.assumeTrue(tapl.isTablet)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
index de78f09d3ef4..e94da8713b43 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -67,6 +68,7 @@ open class EnterSplitScreenByDragFromNotificationBenchmark(override val flicker:
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
index a29eb4085e54..f41117f0d54e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -70,6 +71,7 @@ open class EnterSplitScreenByDragFromShortcutBenchmark(flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
index b2395cafafc1..12f610b73e13 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -65,6 +66,7 @@ open class EnterSplitScreenByDragFromTaskbarBenchmark(override val flicker: Flic
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
index e1d85d0a4371..77818d380053 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -64,6 +65,7 @@ open class EnterSplitScreenFromOverviewBenchmark(override val flicker: FlickerTe
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index ba8c46091808..6ff22902667c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.Rotation
@@ -134,6 +135,7 @@ open class SwitchAppByDoubleTapDividerBenchmark(override val flicker: FlickerTes
return displayBounds.width > displayBounds.height
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
index bbb2edc621e2..400adea8880d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -63,6 +64,7 @@ open class SwitchBackToSplitFromAnotherAppBenchmark(override val flicker: Flicke
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
index fa382932eb88..1ec43405ee44 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -61,6 +62,7 @@ open class SwitchBackToSplitFromHomeBenchmark(override val flicker: FlickerTest)
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
index 1064bd93e3c1..9757153929ca 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -61,6 +62,7 @@ open class SwitchBackToSplitFromRecentBenchmark(override val flicker: FlickerTes
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui")
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
index 8f4393f8d20d..c19a38dc9daf 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.splitscreen.benchmark
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -64,6 +65,7 @@ open class SwitchBetweenSplitPairsBenchmark(override val flicker: FlickerTest) :
thisTransition(this)
}
+ @PlatinumTest(focusArea = "sysui")
@IwTest(focusArea = "sysui") @Presubmit @Test open fun cujCompleted() {}
companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
new file mode 100644
index 000000000000..5f16e5b4d65e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class UnlockKeyguardToSplitScreenBenchmark(override val flicker: FlickerTest) :
+ SplitScreenBase(flicker) {
+ protected val thisTransition: FlickerBuilder.() -> Unit
+ get() = {
+ setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+ transitions {
+ device.sleep()
+ wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
+ device.wakeUp()
+ device.pressMenu()
+ wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
+ }
+ }
+
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit
+ get() = {
+ defaultSetup(this)
+ defaultTeardown(this)
+ thisTransition(this)
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): List<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockToken.java
index 09d474d1f97c..a97c19f17412 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/MockToken.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.desktopmode;
+package com.android.wm.shell;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -25,16 +25,16 @@ import android.window.WindowContainerToken;
/**
* {@link WindowContainerToken} wrapper that supports a mock binder
*/
-class MockToken {
+public class MockToken {
private final WindowContainerToken mToken;
- MockToken() {
+ public MockToken() {
mToken = mock(WindowContainerToken.class);
IBinder binder = mock(IBinder.class);
when(mToken.asBinder()).thenReturn(binder);
}
- WindowContainerToken token() {
+ public WindowContainerToken token() {
return mToken;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/LaunchAdjacentControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/LaunchAdjacentControllerTest.kt
new file mode 100644
index 000000000000..9dc816b65d2e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/LaunchAdjacentControllerTest.kt
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.common
+
+import android.os.IBinder
+import android.testing.AndroidTestingRunner
+import android.window.WindowContainerTransaction
+import android.window.WindowContainerTransaction.HierarchyOp
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.MockToken
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class LaunchAdjacentControllerTest : ShellTestCase() {
+
+ private lateinit var controller: LaunchAdjacentController
+
+ @Mock private lateinit var syncQueue: SyncTransactionQueue
+
+ @Before
+ fun setUp() {
+ controller = LaunchAdjacentController(syncQueue)
+ }
+
+ @Test
+ fun newInstance_enabledByDefault() {
+ assertThat(controller.launchAdjacentEnabled).isTrue()
+ }
+
+ @Test
+ fun setLaunchAdjacentRoot_launchAdjacentEnabled_setsFlagRoot() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ val wct = getLatestTransactionOrFail()
+ assertThat(wct.getSetLaunchAdjacentFlagRootContainer()).isEqualTo(token.asBinder())
+ }
+
+ @Test
+ fun setLaunchAdjacentRoot_launchAdjacentDisabled_doesNotUpdateFlagRoot() {
+ val token = MockToken().token()
+ controller.launchAdjacentEnabled = false
+ controller.setLaunchAdjacentRoot(token)
+ verify(syncQueue, never()).queue(any())
+ }
+
+ @Test
+ fun clearLaunchAdjacentRoot_launchAdjacentEnabled_clearsFlagRoot() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ controller.clearLaunchAdjacentRoot()
+ val wct = getLatestTransactionOrFail()
+ assertThat(wct.getClearLaunchAdjacentFlagRootContainer()).isEqualTo(token.asBinder())
+ }
+
+ @Test
+ fun clearLaunchAdjacentRoot_launchAdjacentDisabled_clearsFlagRoot() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ controller.launchAdjacentEnabled = false
+ clearInvocations(syncQueue)
+
+ controller.clearLaunchAdjacentRoot()
+ val wct = getLatestTransactionOrFail()
+ assertThat(wct.getClearLaunchAdjacentFlagRootContainer()).isEqualTo(token.asBinder())
+ }
+
+ @Test
+ fun setLaunchAdjacentEnabled_wasDisabledWithContainerSet_setsFlagRoot() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ controller.launchAdjacentEnabled = false
+ clearInvocations(syncQueue)
+
+ controller.launchAdjacentEnabled = true
+ val wct = getLatestTransactionOrFail()
+ assertThat(wct.getSetLaunchAdjacentFlagRootContainer()).isEqualTo(token.asBinder())
+ }
+
+ @Test
+ fun setLaunchAdjacentEnabled_containerNotSet_doesNotUpdateFlagRoot() {
+ controller.launchAdjacentEnabled = false
+ controller.launchAdjacentEnabled = true
+ verify(syncQueue, never()).queue(any())
+ }
+
+ @Test
+ fun setLaunchAdjacentEnabled_multipleTimes_setsFlagRootOnce() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ controller.launchAdjacentEnabled = true
+ controller.launchAdjacentEnabled = true
+ // Only execute once
+ verify(syncQueue).queue(any())
+ }
+
+ @Test
+ fun setLaunchAdjacentDisabled_containerSet_clearsFlagRoot() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ controller.launchAdjacentEnabled = false
+ val wct = getLatestTransactionOrFail()
+ assertThat(wct.getClearLaunchAdjacentFlagRootContainer()).isEqualTo(token.asBinder())
+ }
+
+ @Test
+ fun setLaunchAdjacentDisabled_containerNotSet_doesNotUpdateFlagRoot() {
+ controller.launchAdjacentEnabled = false
+ verify(syncQueue, never()).queue(any())
+ }
+
+ @Test
+ fun setLaunchAdjacentDisabled_multipleTimes_setsFlagRootOnce() {
+ val token = MockToken().token()
+ controller.setLaunchAdjacentRoot(token)
+ clearInvocations(syncQueue)
+ controller.launchAdjacentEnabled = false
+ controller.launchAdjacentEnabled = false
+ // Only execute once
+ verify(syncQueue).queue(any())
+ }
+
+ private fun getLatestTransactionOrFail(): WindowContainerTransaction {
+ val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
+ verify(syncQueue, atLeastOnce()).queue(arg.capture())
+ return arg.allValues.last().also { assertThat(it).isNotNull() }
+ }
+}
+
+private fun WindowContainerTransaction.getSetLaunchAdjacentFlagRootContainer(): IBinder {
+ return hierarchyOps
+ // Find the operation with the correct type
+ .filter { op -> op.type == HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT }
+ // For set flag root operation, toTop is false
+ .filter { op -> !op.toTop }
+ .map { it.container }
+ .first()
+}
+
+private fun WindowContainerTransaction.getClearLaunchAdjacentFlagRootContainer(): IBinder {
+ return hierarchyOps
+ // Find the operation with the correct type
+ .filter { op -> op.type == HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT }
+ // For clear flag root operation, toTop is true
+ .filter { op -> op.toTop }
+ .map { it.container }
+ .first()
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
new file mode 100644
index 000000000000..9da5ab6f71dd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.common.split;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CURSOR_HOVER_STATES_ENABLED;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.provider.DeviceConfig;
+import android.view.InputDevice;
+import android.view.InsetsState;
+import android.view.MotionEvent;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.DisplayImeController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link DividerView} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DividerViewTest extends ShellTestCase {
+ private @Mock SplitWindowManager.ParentContainerCallbacks mCallbacks;
+ private @Mock SplitLayout.SplitLayoutHandler mSplitLayoutHandler;
+ private @Mock DisplayImeController mDisplayImeController;
+ private @Mock ShellTaskOrganizer mTaskOrganizer;
+ private SplitLayout mSplitLayout;
+ private DividerView mDividerView;
+
+ @Before
+ @UiThreadTest
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ Configuration configuration = getConfiguration();
+ mSplitLayout = new SplitLayout("TestSplitLayout", mContext, configuration,
+ mSplitLayoutHandler, mCallbacks, mDisplayImeController, mTaskOrganizer,
+ SplitLayout.PARALLAX_NONE);
+ SplitWindowManager splitWindowManager = new SplitWindowManager("TestSplitWindowManager",
+ mContext,
+ configuration, mCallbacks);
+ splitWindowManager.init(mSplitLayout, new InsetsState());
+ mDividerView = spy((DividerView) splitWindowManager.getDividerView());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testHoverDividerView() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CURSOR_HOVER_STATES_ENABLED,
+ "true", false);
+
+ Rect dividerBounds = mSplitLayout.getDividerBounds();
+ int x = dividerBounds.centerX();
+ int y = dividerBounds.centerY();
+ long downTime = SystemClock.uptimeMillis();
+ mDividerView.onHoverEvent(getMotionEvent(downTime, MotionEvent.ACTION_HOVER_ENTER, x, y));
+
+ verify(mDividerView, times(1)).setHovering();
+
+ mDividerView.onHoverEvent(getMotionEvent(downTime, MotionEvent.ACTION_HOVER_EXIT, x, y));
+
+ verify(mDividerView, times(1)).releaseHovering();
+
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, CURSOR_HOVER_STATES_ENABLED,
+ "false", false);
+ }
+
+ private static MotionEvent getMotionEvent(long eventTime, int action, float x, float y) {
+ MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
+ properties.id = 0;
+ properties.toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
+
+ MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+ coords.pressure = 1;
+ coords.size = 1;
+ coords.x = x;
+ coords.y = y;
+
+ return MotionEvent.obtain(eventTime, eventTime, action, 1,
+ new MotionEvent.PointerProperties[]{properties},
+ new MotionEvent.PointerCoords[]{coords}, 0, 0, 1.0f, 1.0f, 0, 0,
+ InputDevice.SOURCE_TOUCHSCREEN, 0);
+ }
+
+ private static Configuration getConfiguration() {
+ final Configuration configuration = new Configuration();
+ configuration.unset();
+ configuration.orientation = ORIENTATION_LANDSCAPE;
+ configuration.windowConfiguration.setRotation(0);
+ configuration.windowConfiguration.setBounds(new Rect(0, 0, 1080, 2160));
+ return configuration;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index d6387ee5ae13..605a762a395f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -59,6 +59,7 @@ import android.window.WindowContainerTransaction.HierarchyOp;
import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.wm.shell.MockToken;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 9ce18db9492d..666ef5515f21 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.wm.shell.MockToken
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
@@ -345,6 +346,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun moveTaskToFront_postsWctWithReorderOp() {
+ val task1 = setUpFreeformTask()
+ val task2 = setUpFreeformTask()
+
+ controller.moveTaskToFront(task1)
+
+ val wct = getLatestWct(expectTransition = TRANSIT_TO_FRONT)
+ assertThat(wct.hierarchyOps).hasSize(1)
+ wct.assertReorderAt(index = 0, task1)
+ }
+
+ @Test
fun moveToNextDisplay_noOtherDisplays() {
whenever(rootTaskDisplayAreaOrganizer.displayIds).thenReturn(intArrayOf(DEFAULT_DISPLAY))
val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index cf1ff3214d87..29a757c19d98 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -22,6 +22,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.view.Display.DEFAULT_DISPLAY
+import com.android.wm.shell.MockToken
import com.android.wm.shell.TestRunningTaskInfoBuilder
class DesktopTestHelpers {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index 9189d3dd0327..fb17d8799bda 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -223,7 +223,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
// Put the same component into a task in the background
ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
- doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any());
+ doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null);
@@ -247,7 +247,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
SPLIT_POSITION_BOTTOM_OR_RIGHT);
// Put the same component into a task in the background
doReturn(new ActivityManager.RecentTaskInfo()).when(mRecentTasks)
- .findTaskInBackground(any());
+ .findTaskInBackground(any(), anyInt());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index ae69b3ddd042..4e446c684d86 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -44,11 +44,15 @@ public class SplitTestUtils {
static SplitLayout createMockSplitLayout() {
final Rect dividerBounds = new Rect(48, 0, 52, 100);
+ final Rect bounds1 = new Rect(0, 0, 40, 100);
+ final Rect bounds2 = new Rect(60, 0, 100, 100);
final SurfaceControl leash = createMockSurface();
SplitLayout out = mock(SplitLayout.class);
doReturn(dividerBounds).when(out).getDividerBounds();
doReturn(dividerBounds).when(out).getRefDividerBounds();
doReturn(leash).when(out).getDividerLeash();
+ doReturn(bounds1).when(out).getBounds1();
+ doReturn(bounds2).when(out).getBounds2();
return out;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 80384531e9ae..3b05651f884b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -42,6 +42,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -72,6 +73,7 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.common.split.SplitLayout;
import com.android.wm.shell.transition.Transitions;
@@ -117,13 +119,13 @@ public class SplitTransitionTests extends ShellTestCase {
doReturn(mockExecutor).when(mTransitions).getAnimExecutor();
doReturn(mock(SurfaceControl.Transaction.class)).when(mTransactionPool).acquire();
mSplitLayout = SplitTestUtils.createMockSplitLayout();
- mMainStage = new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
+ mMainStage = spy(new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
- mIconProvider);
+ mIconProvider));
mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
- mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
+ mSideStage = spy(new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
- mIconProvider);
+ mIconProvider));
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
@@ -137,6 +139,8 @@ public class SplitTransitionTests extends ShellTestCase {
.setParentTaskId(mMainStage.mRootTaskInfo.taskId).build();
mSideChild = new TestRunningTaskInfoBuilder()
.setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
+ doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
+ doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
}
@Test
@@ -181,7 +185,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
- new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null,
+ new RemoteTransition(testRemote, "Test"), mStageCoordinator,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
@@ -279,7 +283,7 @@ public class SplitTransitionTests extends ShellTestCase {
// Make sure it cleans-up if recents doesn't restore
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
- mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+ mock(SurfaceControl.Transaction.class));
assertFalse(mStageCoordinator.isSplitScreenVisible());
}
@@ -318,7 +322,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
- mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+ mock(SurfaceControl.Transaction.class));
assertTrue(mStageCoordinator.isSplitScreenVisible());
}
@@ -408,7 +412,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(new TestRemoteTransition(), "Test"),
- mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
+ mStageCoordinator, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
mStageCoordinator.startAnimation(enterTransit, enterInfo,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 6621ab8ce0d8..66b6c62f1dd6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -68,6 +68,7 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.common.split.SplitLayout;
import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
import com.android.wm.shell.sysui.ShellController;
@@ -145,6 +146,8 @@ public class StageCoordinatorTests extends ShellTestCase {
mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
+ doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
+ doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 8115a5d4e89c..ee9f88663326 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -364,6 +364,7 @@ public class StartingSurfaceDrawerTests extends ShellTestCase {
1, HardwareBuffer.USAGE_CPU_READ_RARELY);
return new TaskSnapshot(
System.currentTimeMillis(),
+ 0 /* captureTime */,
new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
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 5a2326b9c393..f941e9501a3f 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
@@ -316,7 +316,8 @@ public class WindowDecorationTests extends ShellTestCase {
releaseOrder.verify(t).remove(captionContainerSurface);
releaseOrder.verify(t).remove(decorContainerSurface);
releaseOrder.verify(t).apply();
- verify(mMockWindowContainerTransaction)
+ // Expect to remove two insets sources, the caption insets and the mandatory gesture insets.
+ verify(mMockWindowContainerTransaction, Mockito.times(2))
.removeInsetsSource(eq(taskInfo.token), any(), anyInt(), anyInt());
}
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 3527eeead1d5..2a6dc7b95c07 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -108,7 +108,7 @@ status_t CursorWindow::maybeInflate() {
{
// Migrate existing contents into new ashmem region
- uint32_t slotsSize = mSize - mSlotsOffset;
+ uint32_t slotsSize = sizeOfSlots();
uint32_t newSlotsOffset = mInflatedSize - slotsSize;
memcpy(static_cast<uint8_t*>(newData),
static_cast<uint8_t*>(mData), mAllocOffset);
@@ -216,11 +216,9 @@ status_t CursorWindow::writeToParcel(Parcel* parcel) {
if (parcel->writeDupFileDescriptor(mAshmemFd)) goto fail;
} else {
// Since we know we're going to be read-only on the remote side,
- // we can compact ourselves on the wire, with just enough padding
- // to ensure our slots stay aligned
- size_t slotsSize = mSize - mSlotsOffset;
- size_t compactedSize = mAllocOffset + slotsSize;
- compactedSize = (compactedSize + 3) & ~3;
+ // we can compact ourselves on the wire.
+ size_t slotsSize = sizeOfSlots();
+ size_t compactedSize = sizeInUse();
if (parcel->writeUint32(compactedSize)) goto fail;
if (parcel->writeBool(false)) goto fail;
void* dest = parcel->writeInplace(compactedSize);
diff --git a/libs/androidfw/include/androidfw/CursorWindow.h b/libs/androidfw/include/androidfw/CursorWindow.h
index 6e55a9a0eb8b..9ec026a19c4c 100644
--- a/libs/androidfw/include/androidfw/CursorWindow.h
+++ b/libs/androidfw/include/androidfw/CursorWindow.h
@@ -90,6 +90,9 @@ public:
inline uint32_t getNumRows() { return mNumRows; }
inline uint32_t getNumColumns() { return mNumColumns; }
+ inline size_t sizeOfSlots() const { return mSize - mSlotsOffset; }
+ inline size_t sizeInUse() const { return mAllocOffset + sizeOfSlots(); }
+
status_t clear();
status_t setNumColumns(uint32_t numColumns);
diff --git a/libs/androidfw/tests/CursorWindow_test.cpp b/libs/androidfw/tests/CursorWindow_test.cpp
index d1cfd03276c2..3cdb31e982b1 100644
--- a/libs/androidfw/tests/CursorWindow_test.cpp
+++ b/libs/androidfw/tests/CursorWindow_test.cpp
@@ -21,9 +21,16 @@
#include "TestHelpers.h"
+// Verify that the memory in use is a multiple of 4 bytes
+#define ASSERT_ALIGNED(w) \
+ ASSERT_EQ(((w)->sizeInUse() & 3), 0); \
+ ASSERT_EQ(((w)->freeSpace() & 3), 0); \
+ ASSERT_EQ(((w)->sizeOfSlots() & 3), 0)
+
#define CREATE_WINDOW_1K \
CursorWindow* w; \
- CursorWindow::create(String8("test"), 1 << 10, &w);
+ CursorWindow::create(String8("test"), 1 << 10, &w); \
+ ASSERT_ALIGNED(w);
#define CREATE_WINDOW_1K_3X3 \
CursorWindow* w; \
@@ -31,11 +38,13 @@
ASSERT_EQ(w->setNumColumns(3), OK); \
ASSERT_EQ(w->allocRow(), OK); \
ASSERT_EQ(w->allocRow(), OK); \
- ASSERT_EQ(w->allocRow(), OK);
+ ASSERT_EQ(w->allocRow(), OK); \
+ ASSERT_ALIGNED(w);
#define CREATE_WINDOW_2M \
CursorWindow* w; \
- CursorWindow::create(String8("test"), 1 << 21, &w);
+ CursorWindow::create(String8("test"), 1 << 21, &w); \
+ ASSERT_ALIGNED(w);
static constexpr const size_t kHalfInlineSize = 8192;
static constexpr const size_t kGiantSize = 1048576;
@@ -49,6 +58,7 @@ TEST(CursorWindowTest, Empty) {
ASSERT_EQ(w->getNumColumns(), 0);
ASSERT_EQ(w->size(), 1 << 10);
ASSERT_EQ(w->freeSpace(), 1 << 10);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, SetNumColumns) {
@@ -60,6 +70,7 @@ TEST(CursorWindowTest, SetNumColumns) {
ASSERT_NE(w->setNumColumns(5), OK);
ASSERT_NE(w->setNumColumns(3), OK);
ASSERT_EQ(w->getNumColumns(), 4);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, SetNumColumnsAfterRow) {
@@ -70,6 +81,7 @@ TEST(CursorWindowTest, SetNumColumnsAfterRow) {
ASSERT_EQ(w->allocRow(), OK);
ASSERT_NE(w->setNumColumns(4), OK);
ASSERT_EQ(w->getNumColumns(), 0);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, AllocRow) {
@@ -83,14 +95,17 @@ TEST(CursorWindowTest, AllocRow) {
ASSERT_EQ(w->allocRow(), OK);
ASSERT_LT(w->freeSpace(), before);
ASSERT_EQ(w->getNumRows(), 1);
+ ASSERT_ALIGNED(w);
// Verify we can unwind
ASSERT_EQ(w->freeLastRow(), OK);
ASSERT_EQ(w->freeSpace(), before);
ASSERT_EQ(w->getNumRows(), 0);
+ ASSERT_ALIGNED(w);
// Can't unwind when no rows left
ASSERT_NE(w->freeLastRow(), OK);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, AllocRowBounds) {
@@ -100,6 +115,7 @@ TEST(CursorWindowTest, AllocRowBounds) {
ASSERT_EQ(w->setNumColumns(60), OK);
ASSERT_EQ(w->allocRow(), OK);
ASSERT_NE(w->allocRow(), OK);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, StoreNull) {
@@ -116,6 +132,7 @@ TEST(CursorWindowTest, StoreNull) {
auto field = w->getFieldSlot(0, 0);
ASSERT_EQ(w->getFieldSlotType(field), CursorWindow::FIELD_TYPE_NULL);
}
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, StoreLong) {
@@ -134,6 +151,7 @@ TEST(CursorWindowTest, StoreLong) {
ASSERT_EQ(w->getFieldSlotType(field), CursorWindow::FIELD_TYPE_INTEGER);
ASSERT_EQ(w->getFieldSlotValueLong(field), 0xcafe);
}
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, StoreString) {
@@ -155,6 +173,7 @@ TEST(CursorWindowTest, StoreString) {
auto actual = w->getFieldSlotValueString(field, &size);
ASSERT_EQ(std::string(actual), "cafe");
}
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, StoreBounds) {
@@ -175,6 +194,7 @@ TEST(CursorWindowTest, StoreBounds) {
ASSERT_EQ(w->getFieldSlot(-1, 0), nullptr);
ASSERT_EQ(w->getFieldSlot(0, -1), nullptr);
ASSERT_EQ(w->getFieldSlot(-1, -1), nullptr);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, Inflate) {
@@ -234,6 +254,7 @@ TEST(CursorWindowTest, Inflate) {
ASSERT_NE(actual, buf);
ASSERT_EQ(memcmp(buf, actual, kHalfInlineSize), 0);
}
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, ParcelEmpty) {
@@ -249,10 +270,12 @@ TEST(CursorWindowTest, ParcelEmpty) {
ASSERT_EQ(w->getNumColumns(), 0);
ASSERT_EQ(w->size(), 0);
ASSERT_EQ(w->freeSpace(), 0);
+ ASSERT_ALIGNED(w);
// We can't mutate the window after parceling
ASSERT_NE(w->setNumColumns(4), OK);
ASSERT_NE(w->allocRow(), OK);
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, ParcelSmall) {
@@ -311,6 +334,7 @@ TEST(CursorWindowTest, ParcelSmall) {
ASSERT_EQ(actualSize, 0);
ASSERT_NE(actual, nullptr);
}
+ ASSERT_ALIGNED(w);
}
TEST(CursorWindowTest, ParcelLarge) {
@@ -364,6 +388,7 @@ TEST(CursorWindowTest, ParcelLarge) {
ASSERT_EQ(actualSize, 0);
ASSERT_NE(actual, nullptr);
}
+ ASSERT_ALIGNED(w);
}
} // android
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 7af6efb7da41..06aed63d8def 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -17,7 +17,6 @@
#include "Properties.h"
#include "Debug.h"
-#include "log/log_main.h"
#ifdef __ANDROID__
#include "HWUIProperties.sysprop.h"
#endif
@@ -220,12 +219,15 @@ RenderPipelineType Properties::getRenderPipelineType() {
return sRenderPipelineType;
}
-void Properties::overrideRenderPipelineType(RenderPipelineType type, bool inUnitTest) {
+void Properties::overrideRenderPipelineType(RenderPipelineType type) {
// If we're doing actual rendering then we can't change the renderer after it's been set.
- // Unit tests can freely change this as often as it wants.
- LOG_ALWAYS_FATAL_IF(sRenderPipelineType != RenderPipelineType::NotInitialized &&
- sRenderPipelineType != type && !inUnitTest,
- "Trying to change pipeline but it's already set.");
+ // Unit tests can freely change this as often as it wants, though, as there's no actual
+ // GL rendering happening
+ if (sRenderPipelineType != RenderPipelineType::NotInitialized) {
+ LOG_ALWAYS_FATAL_IF(sRenderPipelineType != type,
+ "Trying to change pipeline but it's already set");
+ return;
+ }
sRenderPipelineType = type;
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 24e206bbc3b1..bb477449fff0 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -303,7 +303,7 @@ public:
static bool enableRTAnimations;
// Used for testing only to change the render pipeline.
- static void overrideRenderPipelineType(RenderPipelineType, bool inUnitTest = false);
+ static void overrideRenderPipelineType(RenderPipelineType);
static bool runningInEmulator;
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 4cffc6c2efe3..d4e919fefbbd 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -23,13 +23,11 @@
#include <GrDirectContext.h>
#include <GrTypes.h>
#include <android/sync.h>
+#include <gui/TraceUtils.h>
#include <ui/FatVector.h>
#include <vk/GrVkExtensions.h>
#include <vk/GrVkTypes.h>
-#include <cstring>
-
-#include <gui/TraceUtils.h>
#include "Properties.h"
#include "RenderThread.h"
#include "pipeline/skia/ShaderCache.h"
@@ -90,19 +88,6 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe
}
}
-GrVkGetProc VulkanManager::sSkiaGetProp = [](const char* proc_name, VkInstance instance,
- VkDevice device) {
- if (device != VK_NULL_HANDLE) {
- if (strcmp("vkQueueSubmit", proc_name) == 0) {
- return (PFN_vkVoidFunction)VulkanManager::interceptedVkQueueSubmit;
- } else if (strcmp("vkQueueWaitIdle", proc_name) == 0) {
- return (PFN_vkVoidFunction)VulkanManager::interceptedVkQueueWaitIdle;
- }
- return vkGetDeviceProcAddr(device, proc_name);
- }
- return vkGetInstanceProcAddr(instance, proc_name);
-};
-
#define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F)
#define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F)
#define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F)
@@ -138,6 +123,7 @@ VulkanManager::~VulkanManager() {
}
mGraphicsQueue = VK_NULL_HANDLE;
+ mAHBUploadQueue = VK_NULL_HANDLE;
mDevice = VK_NULL_HANDLE;
mPhysicalDevice = VK_NULL_HANDLE;
mInstance = VK_NULL_HANDLE;
@@ -231,7 +217,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
mDriverVersion = physDeviceProperties.driverVersion;
// query to get the initial queue props size
- uint32_t queueCount;
+ uint32_t queueCount = 0;
mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr);
LOG_ALWAYS_FATAL_IF(!queueCount);
@@ -239,11 +225,14 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
std::unique_ptr<VkQueueFamilyProperties[]> queueProps(new VkQueueFamilyProperties[queueCount]);
mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, queueProps.get());
+ constexpr auto kRequestedQueueCount = 2;
+
// iterate to find the graphics queue
mGraphicsQueueIndex = queueCount;
for (uint32_t i = 0; i < queueCount; i++) {
if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
mGraphicsQueueIndex = i;
+ LOG_ALWAYS_FATAL_IF(queueProps[i].queueCount < kRequestedQueueCount);
break;
}
}
@@ -273,7 +262,14 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension);
}
- grExtensions.init(sSkiaGetProp, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
+ auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
+ if (device != VK_NULL_HANDLE) {
+ return vkGetDeviceProcAddr(device, proc_name);
+ }
+ return vkGetInstanceProcAddr(instance, proc_name);
+ };
+
+ grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
mInstanceExtensions.data(), mDeviceExtensions.size(),
mDeviceExtensions.data());
@@ -312,7 +308,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
// and we can't depend on it on all platforms
features.features.robustBufferAccess = VK_FALSE;
- float queuePriorities[1] = {0.0};
+ float queuePriorities[kRequestedQueueCount] = {0.0};
void* queueNextPtr = nullptr;
@@ -345,7 +341,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
queueNextPtr, // pNext
0, // VkDeviceQueueCreateFlags
mGraphicsQueueIndex, // queueFamilyIndex
- 1, // queueCount
+ kRequestedQueueCount, // queueCount
queuePriorities, // pQueuePriorities
};
@@ -403,6 +399,7 @@ void VulkanManager::initialize() {
this->setupDevice(mExtensions, mPhysicalDeviceFeatures2);
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
+ mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue);
if (Properties::enablePartialUpdates && Properties::useBufferAge) {
mSwapBehavior = SwapBehavior::BufferAge;
@@ -416,16 +413,24 @@ static void onGrContextReleased(void* context) {
sk_sp<GrDirectContext> VulkanManager::createContext(GrContextOptions& options,
ContextType contextType) {
+ auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
+ if (device != VK_NULL_HANDLE) {
+ return vkGetDeviceProcAddr(device, proc_name);
+ }
+ return vkGetInstanceProcAddr(instance, proc_name);
+ };
+
GrVkBackendContext backendContext;
backendContext.fInstance = mInstance;
backendContext.fPhysicalDevice = mPhysicalDevice;
backendContext.fDevice = mDevice;
- backendContext.fQueue = mGraphicsQueue;
+ backendContext.fQueue =
+ (contextType == ContextType::kRenderThread) ? mGraphicsQueue : mAHBUploadQueue;
backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex;
backendContext.fMaxAPIVersion = mAPIVersion;
backendContext.fVkExtensions = &mExtensions;
backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2;
- backendContext.fGetProc = sSkiaGetProp;
+ backendContext.fGetProc = std::move(getProc);
LOG_ALWAYS_FATAL_IF(options.fContextDeleteProc != nullptr, "Conflicting fContextDeleteProcs!");
this->incStrong((void*)onGrContextReleased);
@@ -636,8 +641,6 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect)
ALOGE_IF(VK_SUCCESS != err, "VulkanManager::swapBuffers(): Failed to get semaphore Fd");
} else {
ALOGE("VulkanManager::swapBuffers(): Semaphore submission failed");
-
- std::lock_guard<std::mutex> lock(mGraphicsQueueMutex);
mQueueWaitIdle(mGraphicsQueue);
}
if (mDestroySemaphoreContext) {
@@ -652,7 +655,6 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect)
void VulkanManager::destroySurface(VulkanSurface* surface) {
// Make sure all submit commands have finished before starting to destroy objects.
if (VK_NULL_HANDLE != mGraphicsQueue) {
- std::lock_guard<std::mutex> lock(mGraphicsQueueMutex);
mQueueWaitIdle(mGraphicsQueue);
}
mDeviceWaitIdle(mDevice);
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 00a40c0c85c3..2be1ffdbc423 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -17,10 +17,6 @@
#ifndef VULKANMANAGER_H
#define VULKANMANAGER_H
-#include <functional>
-#include <mutex>
-
-#include "vulkan/vulkan_core.h"
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
#define VK_USE_PLATFORM_ANDROID_KHR
#endif
@@ -186,25 +182,8 @@ private:
VkDevice mDevice = VK_NULL_HANDLE;
uint32_t mGraphicsQueueIndex;
-
- std::mutex mGraphicsQueueMutex;
VkQueue mGraphicsQueue = VK_NULL_HANDLE;
-
- static VKAPI_ATTR VkResult interceptedVkQueueSubmit(VkQueue queue, uint32_t submitCount,
- const VkSubmitInfo* pSubmits,
- VkFence fence) {
- sp<VulkanManager> manager = VulkanManager::getInstance();
- std::lock_guard<std::mutex> lock(manager->mGraphicsQueueMutex);
- return manager->mQueueSubmit(queue, submitCount, pSubmits, fence);
- }
-
- static VKAPI_ATTR VkResult interceptedVkQueueWaitIdle(VkQueue queue) {
- sp<VulkanManager> manager = VulkanManager::getInstance();
- std::lock_guard<std::mutex> lock(manager->mGraphicsQueueMutex);
- return manager->mQueueWaitIdle(queue);
- }
-
- static GrVkGetProc sSkiaGetProp;
+ VkQueue mAHBUploadQueue = VK_NULL_HANDLE;
// Variables saved to populate VkFunctorInitParams.
static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0);
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 9d5c13e5cd75..81ecfe59d3bc 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -61,12 +61,12 @@ namespace uirenderer {
ADD_FAILURE() << "ClipState not a rect"; \
}
-#define INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, functionCall) \
- TEST(test_case_name, test_name##_##pipeline) { \
- RenderPipelineType oldType = Properties::getRenderPipelineType(); \
- Properties::overrideRenderPipelineType(RenderPipelineType::pipeline, true); \
- functionCall; \
- Properties::overrideRenderPipelineType(oldType, true); \
+#define INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, functionCall) \
+ TEST(test_case_name, test_name##_##pipeline) { \
+ RenderPipelineType oldType = Properties::getRenderPipelineType(); \
+ Properties::overrideRenderPipelineType(RenderPipelineType::pipeline); \
+ functionCall; \
+ Properties::overrideRenderPipelineType(oldType); \
};
#define INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, pipeline) \
@@ -78,27 +78,29 @@ namespace uirenderer {
* Like gtest's TEST, but runs on the RenderThread, and 'renderThread' is passed, in top level scope
* (for e.g. accessing its RenderState)
*/
-#define RENDERTHREAD_TEST(test_case_name, test_name) \
- class test_case_name##_##test_name##_RenderThreadTest { \
- public: \
- static void doTheThing(renderthread::RenderThread& renderThread); \
- }; \
- INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \
- INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); \
- void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \
+#define RENDERTHREAD_TEST(test_case_name, test_name) \
+ class test_case_name##_##test_name##_RenderThreadTest { \
+ public: \
+ static void doTheThing(renderthread::RenderThread& renderThread); \
+ }; \
+ INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \
+ /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \
+ /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \
+ void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \
renderthread::RenderThread& renderThread)
/**
* Like RENDERTHREAD_TEST, but only runs with the Skia RenderPipelineTypes
*/
-#define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name) \
- class test_case_name##_##test_name##_RenderThreadTest { \
- public: \
- static void doTheThing(renderthread::RenderThread& renderThread); \
- }; \
- INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \
- INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); \
- void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \
+#define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name) \
+ class test_case_name##_##test_name##_RenderThreadTest { \
+ public: \
+ static void doTheThing(renderthread::RenderThread& renderThread); \
+ }; \
+ INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \
+ /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \
+ /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \
+ void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \
renderthread::RenderThread& renderThread)
/**
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2541a506760c..32680dae75b9 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3181,7 +3181,10 @@ final public class MediaCodec {
mValid = false;
mNativeContext = 0;
}
- sPool.offer(this);
+
+ if (!mInternal) {
+ sPool.offer(this);
+ }
}
private native void native_recycle();
@@ -3245,6 +3248,7 @@ final public class MediaCodec {
mNativeContext = context;
mMappable = isMappable;
mValid = (context != 0);
+ mInternal = true;
}
private static final BlockingQueue<LinearBlock> sPool =
@@ -3255,6 +3259,7 @@ final public class MediaCodec {
private boolean mMappable = false;
private ByteBuffer mMapped = null;
private long mNativeContext = 0;
+ private boolean mInternal = false;
}
/**
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 11cb2be6660b..1e3c15419cff 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -81,6 +81,18 @@ public abstract class MediaRoute2ProviderService extends Service {
public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
/**
+ * A category indicating that the associated provider is only intended for use within the app
+ * that hosts the provider.
+ *
+ * <p>Declaring this category helps the system save resources by avoiding the launch of services
+ * whose routes are known to be private to the app that provides them.
+ *
+ * @hide
+ */
+ public static final String CATEGORY_SELF_SCAN_ONLY =
+ "android.media.MediaRoute2ProviderService.SELF_SCAN_ONLY";
+
+ /**
* The request ID to pass {@link #notifySessionCreated(long, RoutingSessionInfo)}
* when {@link MediaRoute2ProviderService} created a session although there was no creation
* request.
diff --git a/media/java/android/media/RouteListingPreference.java b/media/java/android/media/RouteListingPreference.java
index ee1f20308922..3935de837f51 100644
--- a/media/java/android/media/RouteListingPreference.java
+++ b/media/java/android/media/RouteListingPreference.java
@@ -440,14 +440,14 @@ public final class RouteListingPreference implements Parcelable {
* <p>If this method returns {@link #SUBTEXT_CUSTOM}, then the subtext is obtained form
* {@link #getCustomSubtextMessage()}.
*
- * @see #SUBTEXT_NONE,
- * @see #SUBTEXT_ERROR_UNKNOWN,
- * @see #SUBTEXT_SUBSCRIPTION_REQUIRED,
- * @see #SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED,
- * @see #SUBTEXT_AD_ROUTING_DISALLOWED,
- * @see #SUBTEXT_DEVICE_LOW_POWER,
- * @see #SUBTEXT_UNAUTHORIZED ,
- * @see #SUBTEXT_TRACK_UNSUPPORTED,
+ * @see #SUBTEXT_NONE
+ * @see #SUBTEXT_ERROR_UNKNOWN
+ * @see #SUBTEXT_SUBSCRIPTION_REQUIRED
+ * @see #SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED
+ * @see #SUBTEXT_AD_ROUTING_DISALLOWED
+ * @see #SUBTEXT_DEVICE_LOW_POWER
+ * @see #SUBTEXT_UNAUTHORIZED
+ * @see #SUBTEXT_TRACK_UNSUPPORTED
* @see #SUBTEXT_CUSTOM
*/
@SubText
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 85b02ad54718..720d9a6291de 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -63,6 +63,7 @@ import android.widget.FrameLayout;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -1009,6 +1010,13 @@ public abstract class TvInputService extends Service {
* @param buffer the {@link AdBuffer} that was consumed.
*/
public void notifyAdBufferConsumed(@NonNull AdBuffer buffer) {
+ AdBuffer dupBuffer;
+ try {
+ dupBuffer = AdBuffer.dupAdBuffer(buffer);
+ } catch (IOException e) {
+ Log.w(TAG, "dup AdBuffer error in notifyAdBufferConsumed:", e);
+ return;
+ }
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@Override
@@ -1016,10 +1024,14 @@ public abstract class TvInputService extends Service {
try {
if (DEBUG) Log.d(TAG, "notifyAdBufferConsumed");
if (mSessionCallback != null) {
- mSessionCallback.onAdBufferConsumed(buffer);
+ mSessionCallback.onAdBufferConsumed(dupBuffer);
}
} catch (RemoteException e) {
Log.w(TAG, "error in notifyAdBufferConsumed", e);
+ } finally {
+ if (dupBuffer != null) {
+ dupBuffer.getSharedMemory().close();
+ }
}
}
});
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index ec85cc7af499..241940486a14 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -1964,6 +1964,13 @@ public abstract class TvInteractiveAppService extends Service {
*/
@CallSuper
public void notifyAdBufferReady(@NonNull AdBuffer buffer) {
+ AdBuffer dupBuffer;
+ try {
+ dupBuffer = AdBuffer.dupAdBuffer(buffer);
+ } catch (IOException e) {
+ Log.w(TAG, "dup AdBuffer error in notifyAdBufferReady:", e);
+ return;
+ }
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@Override
@@ -1974,10 +1981,14 @@ public abstract class TvInteractiveAppService extends Service {
"notifyAdBufferReady(buffer=" + buffer + ")");
}
if (mSessionCallback != null) {
- mSessionCallback.onAdBufferReady(AdBuffer.dupAdBuffer(buffer));
+ mSessionCallback.onAdBufferReady(dupBuffer);
}
- } catch (RemoteException | IOException e) {
+ } catch (RemoteException e) {
Log.w(TAG, "error in notifyAdBuffer", e);
+ } finally {
+ if (dupBuffer != null) {
+ dupBuffer.getSharedMemory().close();
+ }
}
}
});
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index ca1bb3e97815..da2e56f5b6fa 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -768,6 +768,7 @@ static void ImageReader_unlockGraphicBuffer(JNIEnv* env, jobject /*thiz*/,
android_graphics_GraphicBuffer_getNativeGraphicsBuffer(env, buffer);
if (graphicBuffer.get() == NULL) {
jniThrowRuntimeException(env, "Invalid graphic buffer!");
+ return;
}
status_t res = graphicBuffer->unlock();
diff --git a/packages/CarrierDefaultApp/assets/slice_purchase_test.html b/packages/CarrierDefaultApp/assets/slice_purchase_test.html
index 67d218413e74..917276b9ce65 100644
--- a/packages/CarrierDefaultApp/assets/slice_purchase_test.html
+++ b/packages/CarrierDefaultApp/assets/slice_purchase_test.html
@@ -20,7 +20,7 @@
<meta charset="UTF-8">
<meta name="description" content="
This is a HTML page that calls and verifies responses from the @JavascriptInterface functions of
- SlicePurchaseWebInterface. Test slice purchase application behavior using ADB shell commands and
+ DataBoostWebServiceFlow. Test slice purchase application behavior using ADB shell commands and
the APIs below:
FROM TERMINAL:
@@ -65,8 +65,8 @@
<p id="requested_capability"></p>
<h2>Notify purchase successful</h2>
- <button type="button" onclick="testNotifyPurchaseSuccessful(60000)">
- Notify purchase successful for 1 minute
+ <button type="button" onclick="testNotifyPurchaseSuccessful()">
+ Notify purchase successful
</button>
<p id="purchase_successful"></p>
@@ -75,5 +75,11 @@
Notify purchase failed
</button>
<p id="purchase_failed"></p>
+
+ <h2>Dismiss flow</h2>
+ <button type="button" onclick="testDismissFlow()">
+ Dismiss flow
+ </button>
+ <p id="dismiss_flow"></p>
</body>
</html>
diff --git a/packages/CarrierDefaultApp/assets/slice_purchase_test.js b/packages/CarrierDefaultApp/assets/slice_purchase_test.js
index 02c4feac7ee4..be397a115921 100644
--- a/packages/CarrierDefaultApp/assets/slice_purchase_test.js
+++ b/packages/CarrierDefaultApp/assets/slice_purchase_test.js
@@ -15,19 +15,25 @@
*/
function testGetRequestedCapability() {
- let capability = SlicePurchaseWebInterface.getRequestedCapability();
+ let capability = DataBoostWebServiceFlow.getRequestedCapability();
document.getElementById("requested_capability").innerHTML =
"Premium capability requested: " + capability;
}
-function testNotifyPurchaseSuccessful(duration_ms_long = 0) {
- SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration_ms_long);
+function testNotifyPurchaseSuccessful() {
+ DataBoostWebServiceFlow.notifyPurchaseSuccessful();
document.getElementById("purchase_successful").innerHTML =
- "Notified purchase success for duration: " + duration_ms_long;
+ "Notified purchase successful.";
}
function testNotifyPurchaseFailed(failure_code = 0, failure_reason = "unknown") {
- SlicePurchaseWebInterface.notifyPurchaseFailed(failure_code, failure_reason);
+ DataBoostWebServiceFlow.notifyPurchaseFailed(failure_code, failure_reason);
document.getElementById("purchase_failed").innerHTML =
"Notified purchase failed.";
}
+
+function testDismissFlow() {
+ DataBoostWebServiceFlow.dismissFlow();
+ document.getElementById("dismiss_flow").innerHTML =
+ "Called dismiss flow.";
+}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java
index 8547898df678..4500a220523d 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseWebInterface.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java
@@ -24,13 +24,13 @@ import android.webkit.JavascriptInterface;
import com.android.phone.slice.SlicePurchaseController;
/**
- * Slice purchase web interface class allowing carrier websites to send responses back to the
+ * Data boost web service flow interface allowing carrier websites to send responses back to the
* slice purchase application using JavaScript.
*/
-public class SlicePurchaseWebInterface {
+public class DataBoostWebServiceFlow {
@NonNull SlicePurchaseActivity mActivity;
- public SlicePurchaseWebInterface(@NonNull SlicePurchaseActivity activity) {
+ public DataBoostWebServiceFlow(@NonNull SlicePurchaseActivity activity) {
mActivity = activity;
}
@@ -41,7 +41,7 @@ public class SlicePurchaseWebInterface {
* This can be called using the JavaScript below:
* <script type="text/javascript">
* function getRequestedCapability(duration) {
- * SlicePurchaseWebInterface.getRequestedCapability();
+ * DataBoostWebServiceFlow.getRequestedCapability();
* }
* </script>
*/
@@ -57,16 +57,14 @@ public class SlicePurchaseWebInterface {
*
* This can be called using the JavaScript below:
* <script type="text/javascript">
- * function notifyPurchaseSuccessful(duration_ms_long = 0) {
- * SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration_ms_long);
+ * function notifyPurchaseSuccessful() {
+ * DataBoostWebServiceFlow.notifyPurchaseSuccessful();
* }
* </script>
- *
- * @param duration The duration for which the premium capability is purchased in milliseconds.
*/
@JavascriptInterface
- public void notifyPurchaseSuccessful(long duration) {
- mActivity.onPurchaseSuccessful(duration);
+ public void notifyPurchaseSuccessful() {
+ mActivity.onPurchaseSuccessful();
}
/**
@@ -76,7 +74,7 @@ public class SlicePurchaseWebInterface {
* This can be called using the JavaScript below:
* <script type="text/javascript">
* function notifyPurchaseFailed(failure_code = 0, failure_reason = "unknown") {
- * SlicePurchaseWebInterface.notifyPurchaseFailed();
+ * DataBoostWebServiceFlow.notifyPurchaseFailed();
* }
* </script>
*
@@ -90,4 +88,21 @@ public class SlicePurchaseWebInterface {
@Nullable String failureReason) {
mActivity.onPurchaseFailed(failureCode, failureReason);
}
+
+ /**
+ * Interface method allowing the carrier website to notify the slice purchase application that
+ * the service flow ended prematurely. This can be due to user action, an error in the
+ * web sheet logic, or an error on the network side.
+ *
+ * This can be called using the JavaScript below:
+ * <script type="text/javascript">
+ * function dismissFlow() {
+ * DataBoostWebServiceFlow.dismissFlow();
+ * }
+ * </script>
+ */
+ @JavascriptInterface
+ public void dismissFlow() {
+ mActivity.onDismissFlow();
+ }
}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
index 946185a3c420..2530257d629a 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
@@ -27,26 +27,25 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
+import android.webkit.CookieManager;
import android.webkit.WebView;
import com.android.phone.slice.SlicePurchaseController;
import java.net.URL;
-import java.util.concurrent.TimeUnit;
/**
* Activity that launches when the user clicks on the performance boost notification.
* This will open a {@link WebView} for the carrier website to allow the user to complete the
* premium capability purchase.
* The carrier website can get the requested premium capability using the JavaScript interface
- * method {@code SlicePurchaseWebInterface.getRequestedCapability()}.
+ * method {@code DataBoostWebServiceFlow.getRequestedCapability()}.
* If the purchase is successful, the carrier website shall notify the slice purchase application
* using the JavaScript interface method
- * {@code SlicePurchaseWebInterface.notifyPurchaseSuccessful(duration)}, where {@code duration} is
- * the optional duration of the performance boost.
+ * {@code DataBoostWebServiceFlow.notifyPurchaseSuccessful()}.
* If the purchase was not successful, the carrier website shall notify the slice purchase
* application using the JavaScript interface method
- * {@code SlicePurchaseWebInterface.notifyPurchaseFailed(code, reason)}, where {@code code} is the
+ * {@code DataBoostWebServiceFlow.notifyPurchaseFailed(code, reason)}, where {@code code} is the
* {@link SlicePurchaseController.FailureCode} indicating the reason for failure and {@code reason}
* is the human-readable reason for failure if the failure code is
* {@link SlicePurchaseController#FAILURE_CODE_UNKNOWN}.
@@ -118,15 +117,11 @@ public class SlicePurchaseActivity extends Activity {
setupWebView();
}
- protected void onPurchaseSuccessful(long duration) {
+ protected void onPurchaseSuccessful() {
logd("onPurchaseSuccessful: Carrier website indicated successfully purchased premium "
- + "capability " + TelephonyManager.convertPremiumCapabilityToString(mCapability)
- + (duration > 0 ? " for " + TimeUnit.MILLISECONDS.toMinutes(duration) + " minutes."
- : "."));
- Intent intent = new Intent();
- intent.putExtra(SlicePurchaseController.EXTRA_PURCHASE_DURATION, duration);
- SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponseWithData(mApplicationContext,
- mIntent, SlicePurchaseController.EXTRA_INTENT_SUCCESS, intent);
+ + "capability " + TelephonyManager.convertPremiumCapabilityToString(mCapability));
+ SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
+ mIntent, SlicePurchaseController.EXTRA_INTENT_SUCCESS);
finishAndRemoveTask();
}
@@ -143,6 +138,14 @@ public class SlicePurchaseActivity extends Activity {
finishAndRemoveTask();
}
+ protected void onDismissFlow() {
+ logd("onDismissFlow: Dismiss flow called while purchasing premium capability "
+ + TelephonyManager.convertPremiumCapabilityToString(mCapability));
+ SlicePurchaseBroadcastReceiver.sendSlicePurchaseAppResponse(
+ mIntent, SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED);
+ finishAndRemoveTask();
+ }
+
@Override
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
// Pressing back in the WebView will go to the previous page instead of closing
@@ -174,11 +177,17 @@ public class SlicePurchaseActivity extends Activity {
// Create WebView
mWebView = new WebView(this);
+ // Clear any cookies and state that might be saved from previous sessions
+ CookieManager.getInstance().removeAllCookies(null);
+ CookieManager.getInstance().flush();
+ mWebView.clearCache(true);
+ mWebView.clearHistory();
+
// Enable JavaScript for the carrier purchase website to send results back to
// the slice purchase application.
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(
- new SlicePurchaseWebInterface(this), "SlicePurchaseWebInterface");
+ new DataBoostWebServiceFlow(this), "DataBoostWebServiceFlow");
// Display WebView
setContentView(mWebView);
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
index daf0b42dbd7c..cc103fa98e65 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/SlicePurchaseActivityTest.java
@@ -53,7 +53,9 @@ public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchas
private static final int PHONE_ID = 0;
@Mock PendingIntent mPendingIntent;
+ @Mock PendingIntent mSuccessfulIntent;
@Mock PendingIntent mCanceledIntent;
+ @Mock PendingIntent mRequestFailedIntent;
@Mock CarrierConfigManager mCarrierConfigManager;
@Mock NotificationManager mNotificationManager;
@Mock PersistableBundle mPersistableBundle;
@@ -107,25 +109,28 @@ public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchas
doReturn(true).when(mCanceledIntent).isBroadcast();
doReturn(mCanceledIntent).when(spiedIntent).getParcelableExtra(
eq(SlicePurchaseController.EXTRA_INTENT_CANCELED), eq(PendingIntent.class));
+ doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mSuccessfulIntent).getCreatorPackage();
+ doReturn(true).when(mSuccessfulIntent).isBroadcast();
+ doReturn(mSuccessfulIntent).when(spiedIntent).getParcelableExtra(
+ eq(SlicePurchaseController.EXTRA_INTENT_SUCCESS), eq(PendingIntent.class));
+ doReturn(TelephonyManager.PHONE_PROCESS_NAME).when(mRequestFailedIntent)
+ .getCreatorPackage();
+ doReturn(true).when(mRequestFailedIntent).isBroadcast();
+ doReturn(mRequestFailedIntent).when(spiedIntent).getParcelableExtra(
+ eq(SlicePurchaseController.EXTRA_INTENT_REQUEST_FAILED), eq(PendingIntent.class));
mSlicePurchaseActivity = startActivity(spiedIntent, null, null);
}
@Test
public void testOnPurchaseSuccessful() throws Exception {
- int duration = 5 * 60 * 1000; // 5 minutes
- int invalidDuration = -1;
- mSlicePurchaseActivity.onPurchaseSuccessful(duration);
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mPendingIntent).send(eq(mContext), eq(0), intentCaptor.capture());
- Intent intent = intentCaptor.getValue();
- assertEquals(duration, intent.getLongExtra(
- SlicePurchaseController.EXTRA_PURCHASE_DURATION, invalidDuration));
+ mSlicePurchaseActivity.onPurchaseSuccessful();
+ verify(mSuccessfulIntent).send();
}
@Test
public void testOnPurchaseFailed() throws Exception {
- int failureCode = SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE;
+ int failureCode = SlicePurchaseController.FAILURE_CODE_CARRIER_URL_UNAVAILABLE;
String failureReason = "Server unreachable";
mSlicePurchaseActivity.onPurchaseFailed(failureCode, failureReason);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -142,4 +147,10 @@ public class SlicePurchaseActivityTest extends ActivityUnitTestCase<SlicePurchas
mSlicePurchaseActivity.onDestroy();
verify(mCanceledIntent).send();
}
+
+ @Test
+ public void testOnDismissFlow() throws Exception {
+ mSlicePurchaseActivity.onDismissFlow();
+ verify(mRequestFailedIntent).send();
+ }
}
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 79bf2570c0c4..1082c0a7dcf3 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Metgeseltoestel-bestuurder"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Kies ’n toestel wat &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; moet bestuur"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Kies ’n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om op te stel"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Hierdie app sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, en sal toegang tot hierdie toestemmings op jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hê"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Laat &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toe om &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te bestuur?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"toestel"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Hierdie app sal toegang tot hierdie toestemmings op jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hê"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toestemming om apps tussen jou toestelle te stroom"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en die gekose toestel"</string>
<string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
<string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Kanselleer"</string>
<string name="consent_back" msgid="2560683030046918882">"Terug"</string>
<string name="permission_expand" msgid="893185038020887411">"Vou <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> uit"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Vou <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> in"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index fb1ee81e938b..a625307d849b 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"አጃቢ የመሣሪያ አስተዳዳሪ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ን እንዲደርስ ይፈቀድለት?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; የሚያስተዳድረው መሣሪያ ይምረጡ"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"የሚያዋቅሩት <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን እንዲያሰምር እና እነዚህን ፈቃዶች በእርስዎ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ላይ እንዲደርስ ይፈቀድለታል"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ን እንዲያስተዳድር ይፈቅዳሉ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"መሣሪያ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ይህ መተግበሪያ በእርስዎ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ላይ እነዚህን ፈቃዶች እንዲደርስ ይፈቀድለታል"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን በስልክዎ እና በተመረጠው መሣሪያ መካከል ማስመር ይችላል"</string>
<string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
<string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ይቅር"</string>
<string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ን ዘርጋ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ን ሰብስብ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index e73306fbe5de..f15d71f9547f 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"تطبيق \"مدير الجهاز المصاحب\""</string>
<string name="confirmation_title" msgid="4593465730772390351">"‏هل تريد السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;؟"</string>
<string name="profile_name_watch" msgid="576290739483672360">"الساعة"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"‏اختيار جهاز ليديره تطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" لإعداده"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"سيتم السماح لهذا التطبيق بمزامنة المعلومات، مثلاً اسم المتصل، والوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بإدارة &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"جهاز"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"سيتم السماح لهذا التطبيق بالوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"يطلب تطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" لبثّ محتوى التطبيقات بين أجهزتك."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"سيتمكّن هذا التطبيق من مزامنة المعلومات، مثل اسم المتصل، بين هاتفك والجهاز المحدّد."</string>
<string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
<string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"إلغاء"</string>
<string name="consent_back" msgid="2560683030046918882">"رجوع"</string>
<string name="permission_expand" msgid="893185038020887411">"توسيع <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"تصغير <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index dba1c7002017..4dfe3689667f 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"কম্পেনিয়ন ডিভাইচ মেনেজাৰ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; এক্সেছ কৰিবলৈ দিবনে?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;এ পৰিচালনা কৰিবলগীয়া এটা ডিভাইচ বাছনি কৰক"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ছেট আপ কৰিবলৈ এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"এই এপ্‌টোক ফ’ন কৰা লোকৰ নামৰ দৰে তথ্য ছিংক কৰিবলৈ আৰু আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; পৰিচালনা কৰিবলৈ দিবনে?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইচ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"এই এপ্‌টোক আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"এই এপ্‌টোৱে আপোনাৰ ফ’ন আৰু বাছনি কৰা ডিভাইচটোৰ মাজত কল কৰোঁতাৰ নামৰ দৰে তথ্য ছিংক কৰিব পাৰিব"</string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
<string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"বাতিল কৰক"</string>
<string name="consent_back" msgid="2560683030046918882">"উভতি যাওক"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> বিস্তাৰ কৰক"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> সংকোচন কৰক"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 6e140ce1b031..9fd055c828e9 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Kompanyon Cihaz Meneceri"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazına daxil olmaq icazəsi verilsin?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tərəfindən idarə ediləcək cihaz seçin"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Ayarlamaq üçün <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Bu tətbiq zəng edənin adı kimi məlumatları sinxronlaşdıra, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> bu icazələrə daxil ola biləcək"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazını idarə etmək icazəsi verilsin?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"cihazda"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Bu tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> bu icazələrə daxil ola biləcək"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> adından cihazlar arasında tətbiqləri yayımlamaq icazəsi istəyir"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Tətbiq zəng edənin adı kimi məlumatları telefon ilə seçilmiş cihaz arasında sinxronlaşdıracaq"</string>
<string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
<string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Ləğv edin"</string>
<string name="consent_back" msgid="2560683030046918882">"Geriyə"</string>
<string name="permission_expand" msgid="893185038020887411">"Genişləndirin: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Yığcamlaşdırın: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index a49ecc380c96..9e3b71152578 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Menadžer pridruženog uređaja"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> koji želite da podesite"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Ovoj aplikaciji će biti dozvoljeno da sinhronizuje podatke, poput imena osobe koja upućuje poziv, i pristupa tim dozvolama na vašem uređaju (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite li da dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Ovoj aplikaciji će biti dozvoljeno da pristupa ovim dozvolama na vašem uređaju (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ova aplikacija će moći da sinhronizuje podatke, poput imena osobe koja upućuje poziv, između telefona i odabranog uređaja"</string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Otkaži"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skupi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index b80e1775b737..a9ead164f58a 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Менеджар спадарожнай прылады"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Дазволіць праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ да прылады &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Выберыце прыладу (<xliff:g id="APP_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма &lt;strong&gt;&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Выберыце імя <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для наладжвання"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Гэтая праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) на вашай прыладзе \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" і атрымае наступныя дазволы"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Дазволіць праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; кіраваць прыладай &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"прылада"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Гэтая праграма будзе мець на вашай прыладзе \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" наступныя дазволы"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" на трансляцыю праграм паміж вашымі прыладамі"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) паміж тэлефонам і выбранай прыладай"</string>
<string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Скасаваць"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Разгарнуць <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Згарнуць <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 37c2e6be456f..80b301bc900f 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Да се разреши ли на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до устройството &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Изберете устройство, което да се управлява от &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, за да го настроите"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Това приложение ще получи право да синхронизира различна информация, като например името на обаждащия се, и достъп до следните разрешения за вашия <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешавате ли на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управлява устройството &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"устройство"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Това приложение ще има достъп до следните разрешения за вашето <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Това приложение ще може да синхронизира различна информация, като например името на обаждащия се, между телефона ви и избраното устройство"</string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
<string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Отказ"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Разгъване на <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Свиване на <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 1db4b32516c3..d789ab94c8a8 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; অ্যাক্সেস করার অনুমতি দেবেন?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ঘড়ি"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ম্যানেজ করা যাবে এমন একটি ডিভাইস বেছে নিন"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"সেট-আপ করতে কোনও <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"এই অ্যাপকে, কল করছেন এমন কোনও ব্যক্তির নামের মতো তথ্য সিঙ্ক করতে এবং আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-এ এইসব অনুমতি অ্যাক্সেস করতে দেওয়া হবে"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"আপনি কি &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ম্যানেজ করার জন্য &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-কে অনুমতি দেবেন?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইস"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"এই অ্যাপ আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-এ এইসব অনুমতি অ্যাক্সেস করতে পারবে"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;কে এই অ্যাকশন করতে দেবেন?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই কাজটি করতে দেবেন?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"আশেপাশের ডিভাইসে অ্যাপ ও অন্যান্য সিস্টেম ফিচার স্ট্রিম করার জন্য আপনার <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এর হয়ে <xliff:g id="APP_NAME">%1$s</xliff:g> অনুমতি চেয়ে অনুরোধ করছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic" msgid="1761976003668044801">"এই অ্যাপ, আপনার ফোন এবং বেছে নেওয়া ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কোনও কলারের নাম"</string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
<string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"বাতিল করুন"</string>
<string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> বড় করুন"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> আড়াল করুন"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 63316c0b0bd9..4c7ced2b9f81 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Dozvoliti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da postavite"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aplikaciji će biti dozvoljeni sinhroniziranje informacija, kao što je ime osobe koja upućuje poziv i pristup ovim odobrenjima na uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Dozvoliti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aplikaciji će biti dozvoljen pristup ovim odobrenjima na uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ova aplikacija će moći sinhronizirati informacije, kao što je ime osobe koja upućuje poziv, između vašeg telefona i odabranog uređaja"</string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Otkaži"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširivanje stavke <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sužavanje stavke <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 525ce91163a6..17c912ce8416 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestor de dispositius complementaris"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Tria un dispositiu perquè el gestioni &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> per configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, i accedir a aquests permisos al dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestioni &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositiu"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aquesta aplicació podrà accedir a aquests permisos del dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, entre el teu telèfon i el dispositiu triat"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
<string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancel·la"</string>
<string name="consent_back" msgid="2560683030046918882">"Enrere"</string>
<string name="permission_expand" msgid="893185038020887411">"Desplega <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Replega <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 10dd2219cc22..fe4d1af7870a 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Správce doprovodných zařízení"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vyberte zařízení, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete nastavit"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, a získat na zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g> přístup k těmto oprávněním"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; spravovat zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"zařízení"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Tato aplikace bude mít ve vašem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> povolený přístup k těmto oprávněním"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením"</string>
<string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Zrušit"</string>
<string name="consent_back" msgid="2560683030046918882">"Zpět"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozbalit sekci <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sbalit sekci <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 6d400fcdb6b8..072a526d3f85 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Medfølgende enhedsadministrator"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Vil du give &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vælg en enhed, som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Vælg en <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, som du vil konfigurere"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Denne app får tilladelse til at synkronisere oplysninger, f.eks. navne på dem, der ringer, og adgang til disse tilladelser på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du tillade, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; administrerer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"enhed"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Denne app får adgang til disse tilladelser på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Giv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til disse oplysninger fra din telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Denne app vil kunne synkronisere oplysninger som f.eks. navnet på en person, der ringer, mellem din telefon og den valgte enhed"</string>
<string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
<string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Annuller"</string>
<string name="consent_back" msgid="2560683030046918882">"Tilbage"</string>
<string name="permission_expand" msgid="893185038020887411">"Udvid <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skjul <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 06dcd9cc68fe..5a6a20d86752 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Begleitgerät-Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Zulassen, dass &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; auf das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; zugreifen darf?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Gerät auswählen, das von &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; verwaltet werden soll"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> zum Einrichten auswählen"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Diese App darf dann Daten wie den Namen eines Anrufers synchronisieren und auf diese Berechtigungen auf deinem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> zugreifen"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Zulassen, dass &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; verwalten darf"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"Gerät"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Diese App darf dann auf diese Berechtigungen auf deinem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> zugreifen:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren"</string>
<string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
<string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Abbrechen"</string>
<string name="consent_back" msgid="2560683030046918882">"Zurück"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> maximieren"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> minimieren"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 6f81a3530aef..f7689af7316b 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Διαχείριση συνοδευτικής εφαρμογής"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Να επιτρέπεται στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση στη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Επιλέξτε μια συσκευή για διαχείριση μέσω της εφαρμογής &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για ρύθμιση"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες, όπως το όνομα ενός ατόμου που σας καλεί, και να αποκτά πρόσβαση σε αυτές τις άδειες στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Να επιτρέπεται στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να διαχειρίζεται τη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"συσκευή"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Αυτή η εφαρμογή θα μπορεί να έχει πρόσβαση σε αυτές τις άδειες στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της επιλεγμένης συσκευής σας, όπως το όνομα ενός ατόμου που σας καλεί."</string>
<string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
<string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Ακύρωση"</string>
<string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
<string name="permission_expand" msgid="893185038020887411">"Ανάπτυξη <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Σύμπτυξη <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index f70b80e270ed..66a547dd00ef 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index f70b80e270ed..66a547dd00ef 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index f70b80e270ed..66a547dd00ef 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancel"</string>
<string name="consent_back" msgid="2560683030046918882">"Back"</string>
<string name="permission_expand" msgid="893185038020887411">"Expand <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Collapse <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index a41a9ea05e3a..41d29bd6e2c0 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Administrador de dispositivo complementario"</string>
<string name="confirmation_title" msgid="4593465730772390351">"¿Quieres permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Elige un dispositivo para que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; lo administre"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Esta app podrá sincronizar información, como el nombre de alguien cuando te llame, y acceder a los siguientes permisos en tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; administre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Esta app podrá acceder a los siguientes permisos en tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Esta app podrá sincronizar información, como el nombre de la persona que llama, entre el teléfono y el dispositivo elegido"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_expand" msgid="893185038020887411">"Expandir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index f3c2923db9e4..9681de6f6304 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos complementario"</string>
<string name="confirmation_title" msgid="4593465730772390351">"¿Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a tu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Elige un dispositivo para que lo gestione &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Elige el <xliff:g id="PROFILE_NAME">%1$s</xliff:g> que quieras configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Esta aplicación podrá sincronizar información, como el nombre de la persona que llama, y acceder a estos permisos de tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"¿Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestione &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Esta aplicación podrá acceder a estos permisos de tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Esta aplicación podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) entre tu teléfono y el dispositivo que elijas"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_expand" msgid="893185038020887411">"Desplegar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 4da6dec62476..e8c16e6f883d 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Kaasseadme haldur"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Andke rakendusele &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; juurdepääs seadmele &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Valige seade, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Valige <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mis seadistada"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Sellel rakendusel lubatakse sünkroonida teavet (nt helistaja nime) ja antakse need load teie seadmes <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hallata seadet &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"seade"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Sellele rakendusele antakse need load teie seadmes <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja valitud seadme vahel"</string>
<string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
<string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Tühista"</string>
<string name="consent_back" msgid="2560683030046918882">"Tagasi"</string>
<string name="permission_expand" msgid="893185038020887411">"Laienda: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ahenda: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index c8cb2a00828f..3bcca29a80c5 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gailu osagarriaren kudeatzailea"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; erabiltzeko baimena eman nahi diozu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Aukeratu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioak kudeatu behar duen gailua"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Aukeratu konfiguratu nahi duzun <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Informazioa sinkronizatu (esate baterako, deitzaileen izenak) eta baimen hauek erabili ahalko ditu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>n aplikazioak"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; kudeatzeko baimena eman nahi diozu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"gailua"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Baimen hauek erabili ahalko ditu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>n aplikazioak:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Telefonoaren eta hautatutako gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)"</string>
<string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
<string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Utzi"</string>
<string name="consent_back" msgid="2560683030046918882">"Atzera"</string>
<string name="permission_expand" msgid="893185038020887411">"Zabaldu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Tolestu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index fa48bf95dd1e..2adb4d8e70ae 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"مدیر دستگاه مرتبط"</string>
<string name="confirmation_title" msgid="4593465730772390351">"‏به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه داده شود به &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; دسترسی پیدا کند؟"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"‏انتخاب دستگاه برای مدیریت کردن با &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای راه‌اندازی"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"به این برنامه اجازه داده می‌شود اطلاعاتی مثل نام تماس‌گیرنده را همگام‌سازی کند و به این اجازه‌ها در <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما دسترسی داشته باشد"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"‏به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه داده شود &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; را مدیریت کند؟"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"دستگاه"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"این برنامه مجاز می‌شود به این اجازه‌ها در <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما دسترسی پیدا کند"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> اجازه می‌خواهد برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"این برنامه مجاز می‌شود اطلاعتی مثل نام شخصی را که تماس می‌گیرد بین تلفن شما و دستگاه انتخاب‌شده همگام‌سازی کند"</string>
<string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string>
<string name="consent_no" msgid="2640796915611404382">"اجازه ندادن"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"لغو"</string>
<string name="consent_back" msgid="2560683030046918882">"برگشتن"</string>
<string name="permission_expand" msgid="893185038020887411">"ازهم بازکردن <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"جمع کردن <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index e73356662c4c..11831b62c60e 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Sallitaanko, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn laitteeseen: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"kello"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Valitse laite, jota &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hallinnoi"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, niin voit suorittaa käyttöönoton"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Sovellus saa luvan synkronoida tietoja (esimerkiksi soittajan nimen) ja pääsyn näihin lupiin laitteella (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa ylläpitää laitetta: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"laite"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Tämä sovellus saa käyttää näitä lupia laitteella (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn näihin puhelimesi tietoihin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja valitun laitteen välillä"</string>
<string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
<string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Peruuta"</string>
<string name="consent_back" msgid="2560683030046918882">"Takaisin"</string>
<string name="permission_expand" msgid="893185038020887411">"Laajenna <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Tiivistä <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 756fdbed9ceb..80f4f22831d5 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareil compagnon"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choisir un appareil qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Choisir un appareil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) pour le configurer"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Cette application sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Cette application pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Annuler"</string>
<string name="consent_back" msgid="2560683030046918882">"Retour"</string>
<string name="permission_expand" msgid="893185038020887411">"Développer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Réduire <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index cec399a34465..04694702ca37 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareils associés"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Sélectionner l\'appareil qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Sélectionner votre <xliff:g id="PROFILE_NAME">%1$s</xliff:g> à configurer"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Cette appli sera autorisée à synchroniser des infos (comme le nom de l\'appelant) et disposera de ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Cette appli sera autorisée à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Cette appli pourra synchroniser des infos, comme le nom de l\'appelant, entre votre téléphone et l\'appareil choisi"</string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Annuler"</string>
<string name="consent_back" msgid="2560683030046918882">"Retour"</string>
<string name="permission_expand" msgid="893185038020887411">"Développer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Réduire <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 3376d648dea7..be232e9b3001 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Xestor de dispositivos complementarios"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Queres permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda ao dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <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="summary_watch" msgid="7962014927042971830">"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_NAME">%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>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Esta aplicación poderá acceder a estes permisos do dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) para emitir contido de aplicacións entre os teus aparellos"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) entre o teléfono e o dispositivo escollido"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
<string name="permission_expand" msgid="893185038020887411">"Despregar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Contraer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 9ea258843851..22b9d3902374 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"કમ્પેનિયન ડિવાઇસ મેનેજર"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; દ્વારા મેનેજ કરવા માટે કોઈ ડિવાઇસ પસંદ કરો"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"સેટઅપ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"આ ઍપને, કૉલ કરનાર વ્યક્તિનું નામ જેવી માહિતી સિંક કરવાની અને તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g> પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; મેનેજ કરવા માટે મંજૂરી આપીએ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ડિવાઇસ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"આ ઍપને તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g> પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી મળશે"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"આ ઍપ તમારા ફોન અને પસંદ કરેલા ડિવાઇસ વચ્ચે, કૉલ કરનાર કોઈ વ્યક્તિનું નામ જેવી માહિતી સિંક કરી શકશે"</string>
<string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
<string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"રદ કરો"</string>
<string name="consent_back" msgid="2560683030046918882">"પાછળ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ને મોટું કરો"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>ને નાનું કરો"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index 7c4d2d0cf88e..82eeecd3559b 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"सहयोगी डिवाइस मैनेजर"</string>
<string name="confirmation_title" msgid="4593465730772390351">"क्या &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; को ऐक्सेस करने के लिए &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अनुमति देनी है?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; से मैनेज किया जाने वाला डिवाइस चुनें"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"सेट अप करने के लिए कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_NAME">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस करने के साथ-साथ कॉल करने वाले व्यक्ति के नाम जैसी जानकारी सिंक कर पाएगा"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"क्या &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; मैनेज करने की अनुमति देनी है?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"डिवाइस"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_NAME">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस कर पाएगा"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन स्ट्रीम करने की अनुमति मांग रहा है"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक करेगा. जैसे, कॉल करने वाले व्यक्ति का नाम"</string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"रद्द करें"</string>
<string name="consent_back" msgid="2560683030046918882">"वापस जाएं"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> को बड़ा करें"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> को छोटा करें"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इनमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"अपने फ़ोन पर मौजूद ऐप्लिकेशन स्ट्रीम करें"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"अपने फ़ोन से ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को स्ट्रीम करें"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"अपने फ़ोन से ऐप्लिकेशन और सिस्टम की दूसरी सुविधाओं को स्ट्रीम करें"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"फ़ोन"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"टैबलेट"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index cbb71261b770..fc1a750e2f88 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Želite li dopustiti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"satom"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> koji želite postaviti"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aplikacija će moći sinkronizirati podatke kao što je ime pozivatelja i pristupiti tim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Dopustiti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aplikacija će moći pristupati ovim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za stream aplikacija s jednog uređaja na drugi"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Dopustiti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; da izvede tu radnju?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Želite li uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dopustiti da izvrši tu radnju?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> za emitiranje aplikacija i drugih značajki sustava na uređajima u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja"</string>
<string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
<string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Odustani"</string>
<string name="consent_back" msgid="2560683030046918882">"Natrag"</string>
<string name="permission_expand" msgid="893185038020887411">"Proširi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sažmi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streaming aplikacija vašeg telefona"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emitiranje aplikacija i drugih značajki sustava s vašeg telefona"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emitirajte stream aplikacija i drugih značajki sustava s vašeg telefona"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"telefonu"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tabletu"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index de801df5cd52..4f7448698aad 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Társeszközök kezelője"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Engedélyezi a(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hozzáférését a következőhöz: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"óra"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; alkalmazással kezelni kívánt eszköz kiválasztása"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Válassza ki a beállítani kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> nevet."</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Ez az alkalmazás képes lesz szinkronizálni információkat (például a hívó fél nevét), és hozzáférhet majd ezekhez az engedélyekhez az Ön <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközén"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Engedélyezi, hogy a(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; kezelje a következő eszközt: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"eszköz"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Az alkalmazás hozzáférhet majd ezekhez az engedélyekhez az Ön <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközén"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ez az alkalmazás képes lesz szinkronizálni az olyan információkat a telefon és a kiválasztott eszköz között, mint például a hívó fél neve."</string>
<string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
<string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Mégse"</string>
<string name="consent_back" msgid="2560683030046918882">"Vissza"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> kibontása"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> összecsukása"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index c5e1ee75f76c..c6edd8929c91 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Թույլատրե՞լ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կառավարել &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքը"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Ընտրեք սարքը, որը պետք է կառավարվի &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածի միջոցով"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Կարգավորելու համար ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Այս հավելվածը կկարողանա համաժամացնել տվյալները, օր․՝ զանգողի անունը, և կստանա հետևյալ թույլտվությունները ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ում"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Թույլատրե՞լ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կառավարել &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքը"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"սարք"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Այս հավելվածը կստանա հետևյալ թույլտվությունները ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ում"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը"</string>
<string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
<string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Չեղարկել"</string>
<string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
<string name="permission_expand" msgid="893185038020887411">"Ծավալել «<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>» բաժինը"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ծալել «<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>» բաժինը"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index e31ea5c1b877..6feff7354dd4 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Pengelola Perangkat Pendamping"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pilih perangkat untuk dikelola oleh &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk disiapkan"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aplikasi ini akan diizinkan menyinkronkan info, seperti nama penelepon, dan mengakses izin ini di <xliff:g id="DEVICE_NAME">%1$s</xliff:g> Anda"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengelola &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"perangkat"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aplikasi ini akan diizinkan mengakses izin ini di <xliff:g id="DEVICE_NAME">%1$s</xliff:g> Anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses informasi ini dari ponsel Anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih"</string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Batalkan"</string>
<string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
<string name="permission_expand" msgid="893185038020887411">"Luaskan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ciutkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -70,7 +64,7 @@
<string name="permission_contacts_summary" msgid="675861979475628708">"Dapat mengakses kontak Anda"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Dapat mengakses kalender Anda"</string>
<string name="permission_microphone_summary" msgid="3692091540613093394">"Dapat merekam audio"</string>
- <string name="permission_nearby_devices_summary" msgid="931940524460876655">"Dapat menemukan, menghubungkan, dan menentukan posisi relatif dari perangkat di sekitar"</string>
+ <string name="permission_nearby_devices_summary" msgid="931940524460876655">"Dapat menemukan, terhubung ke, dan menentukan posisi relatif perangkat di sekitar"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streaming aplikasi ponsel"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index 8d002608094f..283d0e6c670b 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Stjórnun fylgdartækja"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"úr"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Veldu tæki sem &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; á að stjórna"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Veldu <xliff:g id="PROFILE_NAME">%1$s</xliff:g> til að setja upp"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Þetta forrit fær heimild til að samstilla upplýsingar, t.d. nafn þess sem hringir, og fær aðgang að eftirfarandi heimildum í <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Leyfa &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; að stjórna &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"tæki"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Þetta forrit fær aðgang að eftirfarandi heimildum í <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> biður um heimild fyrir <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til að streyma forritum á milli tækjanna þinna"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Þetta forrit mun geta samstillt upplýsingar, t.d. nafn þess sem hringir, á milli símans og valins tækis"</string>
<string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
<string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Hætta við"</string>
<string name="consent_back" msgid="2560683030046918882">"Til baka"</string>
<string name="permission_expand" msgid="893185038020887411">"Stækka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Minnka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index fe4e7ede49bb..dfbd2f5d4cc7 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestione dispositivi companion"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Vuoi consentire all\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"orologio"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Scegli un dispositivo che sia gestito da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da configurare"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, e accedere alle seguenti autorizzazioni su <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Vuoi consentire all\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di gestire &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Questa app potrà accedere alle seguenti autorizzazioni su <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e il dispositivo scelto"</string>
<string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
<string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Annulla"</string>
<string name="consent_back" msgid="2560683030046918882">"Indietro"</string>
<string name="permission_expand" msgid="893185038020887411">"Espandi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Comprimi <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Trasmetti in streaming le app del tuo telefono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Consente di trasmettere in streaming app e altre funzionalità di sistema dal telefono"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Trasmettere in streaming app e altre funzionalità di sistema dal telefono"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"telefono"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index b0f86c260e9f..13e514c635a6 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string>
<string name="confirmation_title" msgid="4593465730772390351">"‏לאשר לאפליקציה ‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&amp;g;‎‏ לגשת אל ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎‏?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"שעון"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"‏בחירה של מכשיר לניהול באמצעות &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"בחירת <xliff:g id="PROFILE_NAME">%1$s</xliff:g> להגדרה"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, ולגשת להרשאות האלה ב<xliff:g id="DEVICE_NAME">%1$s</xliff:g> שלך"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"‏מתן הרשאה לאפליקציה ‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&amp;g;‎‏ לנהל את ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎‏"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"מכשיר"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"האפליקציה הזו תוכל לגשת להרשאות האלה ב<xliff:g id="DEVICE_NAME">%1$s</xliff:g> שלך"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור המכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך למכשיר שבחרת"</string>
<string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
<string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ביטול"</string>
<string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
<string name="permission_expand" msgid="893185038020887411">"הרחבה של <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"כיווץ של <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 6ac04faa5e76..4ddef248fe31 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; へのアクセスを許可しますか?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; の管理対象となるデバイスの選択"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"設定する<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"このアプリは、通話相手の名前などの情報を同期したり、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の以下の権限にアクセスしたりできるようになります"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理を許可しますか?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"デバイス"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"このアプリは、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の以下の権限にアクセスできるようになります"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"このアプリは、あなたのスマートフォンと選択したデバイスとの間で、通話相手の名前などの情報を同期できるようになります"</string>
<string name="consent_yes" msgid="8344487259618762872">"許可"</string>
<string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"キャンセル"</string>
<string name="consent_back" msgid="2560683030046918882">"戻る"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>を開く"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>を閉じる"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index ce57be7c648b..995b4e704a08 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"კომპანიონი მოწყობილობების მენეჯერი"</string>
<string name="confirmation_title" msgid="4593465730772390351">"მიანიჭებთ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; მოწყობილობაზე წვდომას?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"საათი"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"აირჩიეთ მოწყობილობა, რომელიც უნდა მართოს &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპმა"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> დასაყენებლად"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ეს აპი შეძლებს, დაასინქრონოს ინფორმაცია, მაგალითად, შემომავალი ზარის ავტორის სახელი და წვდომა იქონიოს ამ ნებართვებზე თქვენს <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ში"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"ნება დართეთ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/strong&gt; მართოს &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"მოწყობილობა"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ეს აპი შეძლებს ამ ნებართვებზე წვდომას თქვენს <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ში"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ეს აპი შეძლებს ინფორმაციის სინქრონიზებას თქვენს ტელეფონსა და თქვენ მიერ არჩეულ მოწყობილობას შორის, მაგალითად, იმ ადამიანის სახელის, რომელიც გირეკავთ"</string>
<string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
<string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"გაუქმება"</string>
<string name="consent_back" msgid="2560683030046918882">"უკან"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-ის გაფართოება"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-ის ჩაკეცვა"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 5771113c4b58..0330d962dea8 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысын пайдалануға рұқсат беру керек пе?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сағат"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; арқылы басқарылатын құрылғыны таңдаңыз"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Реттеу үшін <xliff:g id="PROFILE_NAME">%1$s</xliff:g> таңдаңыз"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Бұл қолданба қоңырау шалушының аты сияқты деректі синхрондай алады және <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысындағы мына рұқсаттарды пайдалана алады."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысын басқаруға рұқсат беру керек пе?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"құрылғы"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Бұл қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысында осы рұқсаттарды пайдалана алады."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Бұл қолданба телефон мен таңдалған құрылғы арасында деректі (мысалы, қоңырау шалушының атын) синхрондай алады."</string>
<string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
<string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Бас тарту"</string>
<string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
<string name="permission_expand" msgid="893185038020887411">"\"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\" панелін жаю"</string>
<string name="permission_collapse" msgid="3320833884220844084">"\"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\" панелін жию"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 1726907363ff..e9ca811ae769 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"កម្មវិធី​គ្រប់​គ្រង​ឧបករណ៍ដៃគូ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"ជ្រើសរើសឧបករណ៍ ដើម្បីដាក់ក្រោម​ការគ្រប់គ្រងរបស់ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីរៀបចំ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"កម្មវិធីនេះនឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើសមកាលកម្មព័ត៌មាន ដូចជាឈ្មោះមនុស្សដែលហៅទូរសព្ទជាដើម និងចូលប្រើប្រាស់ការអនុញ្ញាតទាំងនេះនៅលើ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; គ្រប់គ្រង &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ឧបករណ៍"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"កម្មវិធីនេះ​នឹងត្រូវបានអនុញ្ញាតឱ្យ​ចូលប្រើប្រាស់ការអនុញ្ញាតទាំងនេះ​នៅលើ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"កម្មវិធីនេះនឹងអាច​ធ្វើសមកាលកម្មព័ត៌មាន ដូចជាឈ្មោះមនុស្សដែលហៅទូរសព្ទជាដើម​ រវាងឧបករណ៍ដែលបានជ្រើសរើស និងទូរសព្ទរបស់អ្នក"</string>
<string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
<string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"បោះបង់"</string>
<string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
<string name="permission_expand" msgid="893185038020887411">"ពង្រីក <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"បង្រួម <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index e8f56ef5a424..06433361d8ac 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ಕಂಪ್ಯಾನಿಯನ್ ಸಾಧನ ನಿರ್ವಾಹಕರು"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ ಸಾಧನವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ಸೆಟಪ್ ಮಾಡಲು <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆರಿಸಿ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಮತ್ತು ಈ ಅನುಮತಿಗಳನ್ನು ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ನಲ್ಲಿ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;? ನಿರ್ವಹಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ಸಾಧನ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ನಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ಸಾಧನದ ನಡುವೆ, ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ"</string>
<string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
<string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ರದ್ದುಮಾಡಿ"</string>
<string name="consent_back" msgid="2560683030046918882">"ಹಿಂದೆ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ಅನ್ನು ವಿಸ್ತರಿಸಿ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ಅನ್ನು ಕುಗ್ಗಿಸಿ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 64941e5e9698..727b766e1475 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;에 액세스하도록 허용하시겠습니까?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 관리할 기기 선택"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"설정할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 선택"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"이 앱이 정보(예: 발신자 이름)를 동기화하고 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 이러한 권한에 액세스할 수 있게 됩니다."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;? 기기를 관리하도록 허용"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"기기"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"앱이 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 이러한 권한에 액세스할 수 있게 됩니다."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;이 휴대전화의 이 정보에 액세스하도록 허용합니다."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"이 앱에서 휴대전화와 선택한 기기 간에 정보(예: 발신자 이름)를 동기화할 수 있게 됩니다."</string>
<string name="consent_yes" msgid="8344487259618762872">"허용"</string>
<string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"취소"</string>
<string name="consent_back" msgid="2560683030046918882">"뒤로"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> 펼치기"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> 접기"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 16ddf3de01a0..c5f3d217d7d9 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүнө кирүүгө уруксат бересизби?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"саат"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; аркылуу башкарыла турган түзмөктү тандаңыз"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Тууралоо үчүн <xliff:g id="PROFILE_NAME">%1$s</xliff:g> тандаңыз"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Бул колдонмого маалыматты, мисалы, чалып жаткан адамдын аты-жөнүн шайкештирүүгө жана <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүн тескөөгө уруксат бересизби?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"түзмөк"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Бул колдонмого <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду алып ойнотууга уруксат сурап жатат"</string>
@@ -40,13 +35,12 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; түзмөгүнө бул аракетти аткарууга уруксат бересизби?"</string>
- <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана тутумдун башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана системанын башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic" msgid="1761976003668044801">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет"</string>
<string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
<string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Жокко чыгаруу"</string>
<string name="consent_back" msgid="2560683030046918882">"Артка"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жайып көрсөтүү"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жыйыштыруу"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Телефондогу колдонмолорду алып ойнотуу"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Телефонуңуздагы колдонмолорду жана тутумдун башка функцияларын алып ойнотуу"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Телефонуңуздагы колдонмолорду жана системанын башка функцияларын алып ойнотуу"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"телефон"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"планшет"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 9c3f1588239e..bdb5fd92e73b 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ຕົວຈັດການອຸປະກອນປະກອບ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ບໍ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"ເລືອກອຸປະກອນທີ່ຈະໃຫ້ມີການຈັດການໂດຍ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ທີ່ຈະຕັ້ງຄ່າ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ແອັບນີ້ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ຊິ້ງຂໍ້ມູນ, ເຊັ່ນ: ຊື່ຂອງຄົນທີ່ໂທເຂົ້າ ແລະ ສິດເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ຈັດການ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ບໍ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ອຸປະກອນ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ແອັບນີ້ຈະໄດ້ຮັບສິດເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຕ່າງໆຂອງທ່ານ"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ແອັບນີ້ຈະສາມາດຊິ້ງຂໍ້ມູນ ເຊັ່ນ: ຊື່ຂອງຄົນທີ່ໂທເຂົ້າ, ລະຫວ່າງໂທລະສັບຂອງທ່ານ ແລະ ອຸປະກອນທີ່ເລືອກໄວ້ໄດ້"</string>
<string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
<string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ຍົກເລີກ"</string>
<string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
<string name="permission_expand" msgid="893185038020887411">"ຂະຫຍາຍ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"ຫຍໍ້ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ລົງ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index be7fbdcfb32a..a32d5b4e1536 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"laikrodį"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Įrenginio, kuris bus valdomas naudojant programą &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, pasirinkimas"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Norimo nustatyti <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pasirinkimas"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Šiai programai bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, ir pasiekti toliau nurodytus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> leidimus"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; valdyti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"įrenginio"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Šiai programai bus leidžiama pasiekti toliau nurodytus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> leidimus."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir pasirinktu įrenginiu"</string>
<string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
<string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Atšaukti"</string>
<string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
<string name="permission_expand" msgid="893185038020887411">"Išskleisti „<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>“"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sutraukti „<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>“"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 7b3507c17c71..94d573e567ff 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Palīgierīču pārzinis"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Vai atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt ierīcei &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Izvēlieties ierīci, ko pārvaldīt lietotnē &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Jāizvēlas <xliff:g id="PROFILE_NAME">%1$s</xliff:g> iestatīšanai"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Šī lietotne drīkstēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, un piekļūt norādītajām atļaujām jūsu ierīcē (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Vai atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt ierīcei &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ierīce"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Šai lietotnei tiks sniegta piekļuve norādītajām atļaujām jūsu ierīcē (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Šī lietotne varēs sinhronizēt informāciju (piemēram, zvanītāja vārdu) starp jūsu tālruni un izvēlēto ierīci"</string>
<string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
<string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Atcelt"</string>
<string name="consent_back" msgid="2560683030046918882">"Atpakaļ"</string>
<string name="permission_expand" msgid="893185038020887411">"Izvērst: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Sakļaut: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index a5f61034634b..249b3c9b96dc 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Ќе дозволите &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Изберете уред со којшто ќе управува &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> за поставување"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Апликацијава ќе има дозвола да ги синхронизира податоците како што се имињата на јавувачите и да пристапува до следниве дозволи на вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Ќе дозволите &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управува со &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"уред"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Апликацијава ќе може да пристапува до овие дозволи на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
@@ -40,13 +35,12 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ќе дозволите &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; да го преземе ова дејство?"</string>
- <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски карактеристики на уредите во близина"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски функции на уредите во близина"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="summary_generic" msgid="1761976003668044801">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и избраниот уред"</string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Откажи"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Прошири <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Собери <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Стримувајте ги апликациите на телефонот"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски карактеристики од вашиот телефон"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски функции од вашиот телефон"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"Телефон"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"Таблет"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index a89a7582af33..a408b65606b0 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"കമ്പാനിയൻ ഉപകരണ മാനേജർ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കണോ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു ഉപകരണം തിരഞ്ഞെടുക്കുക"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"സജ്ജീകരിക്കാൻ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കാനും നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിൽ ഈ അനുമതികൾ ആക്സസ് ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കും"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;? മാനേജ് ചെയ്യാൻ, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കുക"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ഉപകരണം"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിൽ ഇനിപ്പറയുന്ന അനുമതികൾ ആക്സസ് ചെയ്യാൻ ഈ ആപ്പിനെ അനുവദിക്കും"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> എന്ന ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നത് അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും തിരഞ്ഞെടുത്ത ഉപകരണത്തിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും"</string>
<string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
<string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"റദ്ദാക്കുക"</string>
<string name="consent_back" msgid="2560683030046918882">"മടങ്ങുക"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> വികസിപ്പിക്കുക"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ചുരുക്കുക"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 25a81ee113e9..4464c05865e0 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-д &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д хандахыг зөвшөөрөх үү?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"цаг"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-н удирдах төхөөрөмжийг сонгоно уу"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Тохируулахын тулд <xliff:g id="PROFILE_NAME">%1$s</xliff:g> сонгоно уу"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Энэ аппад залгаж буй хүний нэр зэрэг мэдээллийг синк хийх болон таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-н эдгээр зөвшөөрөлд хандахыг зөвшөөрнө"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-г удирдахыг зөвшөөрөх үү?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"төхөөрөмж"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-н эдгээр зөвшөөрөлд хандах эрхтэй байх болно"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон сонгосон төхөөрөмжийн хооронд синк хийх боломжтой болно"</string>
<string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
<string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Цуцлах"</string>
<string name="consent_back" msgid="2560683030046918882">"Буцах"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-г дэлгэх"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>-г хураах"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index f3dfd885bce7..ee699d5cff2b 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"सहयोगी डिव्हाइस व्यवस्थापक"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; अ‍ॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"वॉच"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; द्वारे व्यवस्थापित करण्यासाठी डिव्हाइस निवडा"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"सेट करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"या अ‍ॅपला कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करण्याची आणि तुमच्या <xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर या परवानग्या अ‍ॅक्सेस करण्याची अनुमती असेल"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; व्यवस्थापित करण्याची अनुमती द्यायची आहे?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"डिव्हाइस"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"या अ‍ॅपला तुमच्या <xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर या परवानग्या अ‍ॅक्सेस करण्याची अनुमती असेल"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"हे ॲप तुमचा फोन आणि निवडलेल्या डिव्‍हाइसदरम्यान कॉल करत असलेल्‍या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करू शकेल"</string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"रद्द करा"</string>
<string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> चा विस्तार करा"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> कोलॅप्स करा"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 8949d727298a..04837ff47fa4 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Pengurus Peranti Rakan"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pilih peranti untuk diurus oleh &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk disediakan"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Apl ini akan dibenarkan untuk menyegerakkan maklumat seperti nama individu yang membuat panggilan dan mengakses kebenaran ini pada <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengurus &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"peranti"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Apl ini akan dibenarkan untuk mengakses kebenaran yang berikut pada <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan peranti yang dipilih"</string>
<string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Batal"</string>
<string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
<string name="permission_expand" msgid="893185038020887411">"Kembangkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Kuncupkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 26c5e3c58fdc..9c7048bf0fd0 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"တွဲဖက်ကိရိယာ မန်နေဂျာ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; အား &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;? သုံးခွင့်ပြုခြင်း"</string>
<string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; က စီမံခန့်ခွဲရန် စက်တစ်ခုကို ရွေးပါ"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"စနစ်ထည့်သွင်းရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးပါ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်နှင့် သင့် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> တွင် ၎င်းခွင့်ပြုချက်များရယူရန် ဤအက်ပ်ကိုခွင့်ပြုမည်"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; အား စီမံခွင့်ပြုမလား။"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"စက်"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"သင့် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> တွင် ၎င်းခွင့်ပြုချက်များရယူရန် ဤအက်ပ်ကိုခွင့်ပြုမည်"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် ရွေးထားသောစက်အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်"</string>
<string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
<string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"မလုပ်တော့"</string>
<string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ကို ပိုပြရန်"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ကို လျှော့ပြရန်"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 65e8d2382236..8ecaeba9dc22 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klokke"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Velg en enhet som skal administreres av &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal konfigureres"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Denne appen får tillatelse til å synkronisere informasjon som navnet til noen som ringer, og har disse tillatelsene på <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du la &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; administrere &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"enheten"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Denne appen får disse tillatelsene på <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Denne appen kan synkronisere informasjon som navnet til noen som ringer, mellom telefonen og den valgte enheten"</string>
<string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Avbryt"</string>
<string name="consent_back" msgid="2560683030046918882">"Tilbake"</string>
<string name="permission_expand" msgid="893185038020887411">"Vis <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Skjul <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 62696f6963b0..a5ca130aa1ca 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"सहयोगी डिभाइसको प्रबन्धक"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; प्रयोग गर्ने अनुमति दिने हो?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"घडी"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"आफूले &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; प्रयोग गरी व्यवस्थापन गर्न चाहेको डिभाइस चयन गर्नुहोस्"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"सेट अप गर्नका लागि <xliff:g id="PROFILE_NAME">%1$s</xliff:g> छनौट गर्नुहोस्"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा यो एपलाई कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्ने र यी कुराहरू गर्ने अनुमति दिइने छ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; व्यवस्थापन गर्ने अनुमति दिने हो?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"डिभाइस"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा यो एपलाई निम्न अनुमति दिइने छ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने डिभाइसका बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"रद्द गर्नुहोस्"</string>
<string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> एक्स्पान्ड गर्नुहोस्"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> कोल्याप्स गर्नुहोस्"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 44bf3ce66f5b..8c29b9f3ed2e 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Een apparaat kiezen om te beheren met &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om in te stellen"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Deze app kan informatie synchroniseren (zoals de naam van iemand die belt) en krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toestaan &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te beheren?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"apparaat"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Deze app krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Deze app kan informatie, zoals de naam van iemand die belt, synchroniseren tussen je telefoon en het gekozen apparaat"</string>
<string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
<string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Annuleren"</string>
<string name="consent_back" msgid="2560683030046918882">"Terug"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> uitvouwen"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> samenvouwen"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 7e05bacf30a2..f7d814c42e1b 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ସହଯୋଗୀ ଡିଭାଇସ୍ ପରିଚାଳକ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;କୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ ଡିଭାଇସ ବାଛନ୍ତୁ"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ସେଟ ଅପ କରିବାକୁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ବାଛନ୍ତୁ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏବଂ ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;କୁ ପରିଚାଳନା କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦେବେ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ଡିଭାଇସ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ଆପଣଙ୍କ ଫୋନ ଏବଂ ବଛାଯାଇଥିବା ଡିଭାଇସ ମଧ୍ୟରେ, କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏହି ଆପ ସକ୍ଷମ ହେବ"</string>
<string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>କୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>କୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 9ab12394b32f..3169ded4b3e0 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ਸੰਬੰਧੀ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ"</string>
<string name="confirmation_title" msgid="4593465730772390351">"ਕੀ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ ਕੋਈ ਡੀਵਾਈਸ ਚੁਣੋ"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> \'ਤੇ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰਨ ਅਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"ਕੀ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"ਡੀਵਾਈਸ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> \'ਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਚੁਣੇ ਗਏ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ"</string>
<string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
<string name="consent_no" msgid="2640796915611404382">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ਰੱਦ ਕਰੋ"</string>
<string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ਨੂੰ ਸਮੇਟੋ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 7d3f8aa6cb3c..8daa15baa7e0 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Menedżer urządzeń towarzyszących"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Zezwolić na dostęp aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; do tego urządzenia (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Wybierz urządzenie, którym ma zarządzać aplikacja &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, aby go skonfigurować"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aplikacja będzie mogła synchronizować informacje takie jak nazwa dzwoniącego oraz korzystać z tych uprawnień na Twoim urządzeniu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Zezwolić na dostęp aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; do urządzenia &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"urządzenie"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aplikacja będzie miała dostęp do tych uprawnień na Twoim urządzeniu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól urządzeniu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ta aplikacja może synchronizować informacje takie jak nazwa osoby dzwoniącej między Twoim telefonem i wybranym urządzeniem"</string>
<string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
<string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Anuluj"</string>
<string name="consent_back" msgid="2560683030046918882">"Wstecz"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozwiń sekcję <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Zwiń sekcję <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 793b70608949..c0224da04539 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"O app poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gerencie o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"O app poderá acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize essa ação?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_expand" msgid="893185038020887411">"Abrir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Fechar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Fazer streaming de apps e outros recursos do sistema pelo smartphone"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"smartphone"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 4e1ce5e84c23..cc5f81b70263 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos associados"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Permitir que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda ao &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerido pela app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Escolha um perfil de <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, e aceder a estas autorizações no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; faça a gestão do dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Esta app vai poder aceder a estas autorizações no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; faça esta ação?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer stream de apps e outras funcionalidades do sistema para dispositivos próximos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo escolhido"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_expand" msgid="893185038020887411">"Expandir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Reduzir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 793b70608949..c0224da04539 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"O app poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gerencie o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"O app poderá acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize essa ação?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Cancelar"</string>
<string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
<string name="permission_expand" msgid="893185038020887411">"Abrir <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Fechar <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Fazer streaming de apps e outros recursos do sistema pelo smartphone"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"smartphone"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 0d8579d28292..203cda4eef23 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Manager de dispozitiv Companion"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Permiți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze dispozitivul &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Alege un dispozitiv pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Alege un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> de configurat"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, și să acceseze aceste permisiuni pe <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Permiți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să gestioneze &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"dispozitiv"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Aplicația va putea să acceseze următoarele permisiuni pe <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele tale"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, între telefonul tău și dispozitivul ales"</string>
<string name="consent_yes" msgid="8344487259618762872">"Permite"</string>
<string name="consent_no" msgid="2640796915611404382">"Nu permite"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Anulează"</string>
<string name="consent_back" msgid="2560683030046918882">"Înapoi"</string>
<string name="permission_expand" msgid="893185038020887411">"Extinde <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Restrânge <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index ba452473ed86..1644f0d27d65 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Управление подключенными устройствами"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Предоставить приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ к устройству &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часы"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Выберите устройство, которым будет управлять приложение &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Выберите <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для настройки"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Это приложение сможет синхронизировать данные, например имена вызывающих абонентов, а также получит указанные разрешения на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешить приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; управлять устройством &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"устройстве"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Это приложение получит указанные разрешения на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы транслировать приложения между устройствами."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков."</string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
<string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Отмена"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Разворачивать список \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\"."</string>
<string name="permission_collapse" msgid="3320833884220844084">"Сворачивать список \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\"."</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 877dbf352c40..57a6bce35369 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"සහායක උපාංග කළමනාකරු"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; වෙත ප්‍රවේශ වීමට ඉඩ දෙන්න ද?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; විසින් කළමනා කරනු ලැබීමට උපාංගයක් තෝරන්න"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"සැකසීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"මෙම යෙදුමට අමතන කෙනෙකුගේ නම වැනි, තොරතුරු සමමුහූර්ත කිරීමට, සහ ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> මත මෙම අවසර වෙත ප්‍රවේශ වීමට ඉඩ දෙනු ලැබේ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; කළමනා කිරීමට ඉඩ දෙන්න ද?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"උපාංගය"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"මෙම යෙදුමට ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> මත මෙම අවසර වෙත ප්‍රවේශ වීමට ඉඩ දෙනු ලැබේ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබේ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> වෙනුවෙන් ඔබේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"මෙම යෙදුමට ඔබේ දුරකථනය සහ තෝරා ගත් උපාංගය අතර, අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට හැකි වනු ඇත"</string>
<string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
<string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"අවලංගු කරන්න"</string>
<string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> විදහන්න"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> හකුළන්න"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 51295f8259b2..8279e1ebf470 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Správca sprievodných zariadení"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Chcete povoliť aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k zariadeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vyberte zariadenie, ktoré bude spravovať aplikácia &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý nastavíte"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, a získavať prístup k týmto povoleniam v zariadení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Chcete povoliť aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; spravovať zariadenie &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"zariadenie"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Táto aplikácia bude mať prístup k týmto povoleniam v zariadení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie streamovať aplikácie medzi vašimi zariadeniami."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením"</string>
<string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Zrušiť"</string>
<string name="consent_back" msgid="2560683030046918882">"Späť"</string>
<string name="permission_expand" msgid="893185038020887411">"Rozbaliť sekciu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Zbaliť sekciu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
@@ -74,7 +68,7 @@
<string name="permission_notification_summary" msgid="884075314530071011">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streamovať aplikácie telefónu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Steaming aplikácii a ďalších systémov funkcií zo zariadenia"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Streaming aplikácii a ďalších systémových funkcií zo zariadenia"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"telefón"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index cb47995ebbdf..85d657ddfd56 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Želite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovoliti dostop do naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Izbira naprave, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Izberite profil naprave »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>« za nastavitev"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, in dostopala do teh dovoljenj v napravi »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«."</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovoliti upravljanje naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"naprava"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Ta aplikacija bo lahko dostopala do teh dovoljenj v napravi »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, v telefonu in izbrani napravi."</string>
<string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Prekliči"</string>
<string name="consent_back" msgid="2560683030046918882">"Nazaj"</string>
<string name="permission_expand" msgid="893185038020887411">"Razširi dovoljenje »<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>«"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Strni dovoljenje »<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>«"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 8b1f554adb2b..f7144db0bf23 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string>
<string name="confirmation_title" msgid="4593465730772390351">"T\'i lejohet &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; qasja te &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Zgjidh një pajisje që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Zgjidh një <xliff:g id="PROFILE_NAME">%1$s</xliff:g> për konfigurimin"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Këtij aplikacioni do t\'i lejohet të sinkronizojë informacione, si p.sh. emrin e dikujt që po telefonon, si dhe të ketë qasje në këto leje në <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Të lejohet që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të menaxhojë &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"pajisje"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Këtij aplikacioni do t\'i lejohet qasja te këto leje në <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emrin e dikujt që po telefonon, mes telefonit tënd dhe pajisjes së zgjedhur."</string>
<string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
<string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Anulo"</string>
<string name="consent_back" msgid="2560683030046918882">"Pas"</string>
<string name="permission_expand" msgid="893185038020887411">"Zgjero: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Palos: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 19547475c210..0b634c5df208 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа уређају &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Одаберите уређај којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> који желите да подесите"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Овој апликацији ће бити дозвољено да синхронизује податке, попут имена особе која упућује позив, и приступа тим дозволама на вашем уређају (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Желите ли да дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; управља уређајем &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"уређај"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Овој апликацији ће бити дозвољено да приступа овим дозволама на вашем уређају (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ова апликација ће моћи да синхронизује податке, попут имена особе која упућује позив, између телефона и одабраног уређаја"</string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Откажи"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Прошири <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Скупи <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 0542cc7e3c73..b442412542cf 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Vill du tillåta att &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får åtkomst till &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klocka"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Välj en enhet för hantering av &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för konfigurering"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Appen får tillåtelse att synkronisera information, till exempel namnet på någon som ringer, och få tillgång till dessa behörigheter på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Tillåt att &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hanterar &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"enhet"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Appen får tillåtelse att använda dessa behörigheter på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> streama appar mellan enheter"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Den här appen kommer att kunna synkronisera information mellan telefonen och den valda enheten, till exempel namnet på någon som ringer"</string>
<string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
<string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Avbryt"</string>
<string name="consent_back" msgid="2560683030046918882">"Tillbaka"</string>
<string name="permission_expand" msgid="893185038020887411">"Utöka <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Komprimera <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index b5b0843428cf..92932c7fc397 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Kidhibiti cha Vifaa Visaidizi"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Ungependa kuruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saa"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Chagua kifaa cha kudhibitiwa na &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili uweke mipangilio"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Programu hii itaruhusiwa kusawazisha maelezo, kama vile jina la mtu anayepiga simu na kufikia ruhusa hizi kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Ungependa kuruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; idhibiti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"kifaa"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Programu hii itaruhusiwa kufikia ruhusa hizi kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yako ili itiririshe programu kati ya vifaa vyako"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Programu hii itaweza kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kati ya simu yako na kifaa ulichochagua"</string>
<string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
<string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Ghairi"</string>
<string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
<string name="permission_expand" msgid="893185038020887411">"Panua <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Kunja <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 0d2bb21ba86b..c3fef618c03e 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸால் நிர்வகிக்கப்பட வேண்டிய சாதனத்தைத் தேர்வுசெய்யுங்கள்"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"அமைக்க <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்வுசெய்யவும்"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"அழைப்பவரின் பெயர் போன்ற தகவல்களை ஒத்திசைக்கவும் உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தில் இந்த அனுமதிகளை அணுகவும் இந்த ஆப்ஸ் அனுமதிக்கப்படும்"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&amp;gt சாதனத்தை நிர்வகிக்க &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"சாதனம்"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தில் இந்த அனுமதிகளை அணுக இந்த ஆப்ஸ் அனுமதிக்கப்படும்"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவும்"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&amp;gt சாதனத்தை அனுமதிக்கவா?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ஐ அனுமதிக்கவா?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"அருகிலுள்ள சாதனங்களுக்கு ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic" msgid="1761976003668044801">"அழைப்பவரின் பெயர் போன்ற தகவலை உங்கள் மொபைல் மற்றும் தேர்வுசெய்த சாதனத்திற்கு இடையில் இந்த ஆப்ஸால் ஒத்திசைக்க முடியும்"</string>
<string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
<string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ரத்துசெய்"</string>
<string name="consent_back" msgid="2560683030046918882">"பின்செல்"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ஐ விரிவாக்கும்"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> ஐச் சுருக்கும்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index c15f577d32ee..95a5acefb913 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"సహచర పరికర మేనేజర్"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‌ను యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‌ను అనుమతించాలా?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ద్వారా మేనేజ్ చేయబడే పరికరాన్ని ఎంచుకోండి"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"సెటప్ చేయడానికి <xliff:g id="PROFILE_NAME">%1$s</xliff:g>‌ను ఎంచుకోండి"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని సింక్ చేయడానికి, మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‌ను మేనేజ్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‌ను అనుమతించాలా?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"పరికరం"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని ఈ యాప్ మీ ఫోన్ కు, ఎంచుకున్న పరికరానికీ మధ్య సింక్ చేయగలుగుతుంది"</string>
<string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string>
<string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"రద్దు చేయండి"</string>
<string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>‌ను విస్తరించండి"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>‌ను కుదించండి"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index f108f7cb50ff..dc9e2424d82f 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึง &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"เลือกอุปกรณ์ที่จะให้มีการจัดการโดย &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะตั้งค่า"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"แอปนี้จะได้รับอนุญาตให้ซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา และมีสิทธิ์เข้าถึงข้อมูลเหล่านี้ใน<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ของคุณ"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; จัดการ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ไหม"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"อุปกรณ์"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"แอปนี้จะได้รับสิทธิ์ดังต่อไปนี้ใน<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ของคุณ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและอุปกรณ์ที่เลือกไว้ได้"</string>
<string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
<string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"ยกเลิก"</string>
<string name="consent_back" msgid="2560683030046918882">"กลับ"</string>
<string name="permission_expand" msgid="893185038020887411">"ขยาย <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"ยุบ <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 511c58b48488..f50da1bc7b2f 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Kasamang Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relo"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pumili ng device na papamahalaan ng &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para mag-set up"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Papayagan ang app na ito na mag-sync ng impormasyon, tulad ng pangalan ng taong tumatawag, at i-access ang mga pahintulot na ito sa iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na pamahalaan ang &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Papayagan ang app na ito na i-access ang mga pahintulot na ito sa iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyong ito sa iyong telepono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Magagawa ng app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, sa pagitan ng iyong telepono at ng napiling device"</string>
<string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
<string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Kanselahin"</string>
<string name="consent_back" msgid="2560683030046918882">"Bumalik"</string>
<string name="permission_expand" msgid="893185038020887411">"I-expand ang <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"I-collapse ang <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 297441733aa8..fbe9b02e4ecc 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazına erişmesi için &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasına izin verin"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tarafından yönetilecek bir cihaz seçin"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Ayarlamak için bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Bu uygulamanın arayan kişinin adı gibi bilgileri senkronize etmesine ve <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızda aşağıdaki izinlere erişmesine izin verilir"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasına &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazını yönetmesi için izin verilsin mi?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"cihaz"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Bu uygulamanın <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızda şu izinlere erişmesine izin verilecek:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
@@ -39,14 +34,13 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Hizmetleri"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
- <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlem yapmasına izin verilsin mi?"</string>
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlemi yapmasına izin verilsin mi?"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="1761976003668044801">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir"</string>
<string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
<string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"İptal"</string>
<string name="consent_back" msgid="2560683030046918882">"Geri"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> panelini genişlet"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> panelini daralt"</string>
@@ -65,16 +59,16 @@
<string name="permission_app_streaming" msgid="6009695219091526422">"Uygulamalar"</string>
<string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Yayınlama"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Telefon aramaları yapabilir ve telefon aramalarını yönetebilir"</string>
- <string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon arama kaydını okuma ve yazma"</string>
+ <string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon arama kaydını okuyabilir ve yazabilir"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS mesajları gönderebilir ve görüntüleyebilir"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kişilerinize erişebilir"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Takviminize erişebilir"</string>
<string name="permission_microphone_summary" msgid="3692091540613093394">"Ses kaydedebilir"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Yakındaki cihazları keşfedip bağlanabilir ve bu cihazların göreli konumunu belirleyebilir"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string>
- <string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun uygulamalarını yayınlama"</string>
+ <string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun uygulamalarını yayınlayabilir"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefonunuzdan uygulamaları ve diğer sistem özelliklerini yayınlayın"</string>
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefonunuzdan uygulamaları ve diğer sistem özelliklerini yayınlayabilir"</string>
<string name="device_type" product="default" msgid="8268703872070046263">"telefon"</string>
<string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 3ed63466b5ab..aa7438b24a10 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Диспетчер супутніх пристроїв"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Надати додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до інформації на &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"годинник"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Виберіть пристрій, яким керуватиме додаток &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для налаштування"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) і отримає доступ до перелічених нижче дозволів на вашому <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Дозволити додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; керувати пристроєм &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"пристрій"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Цей додаток матиме доступ до перелічених нижче дозволів на вашому <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) між телефоном і вибраним пристроєм"</string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Скасувати"</string>
<string name="consent_back" msgid="2560683030046918882">"Назад"</string>
<string name="permission_expand" msgid="893185038020887411">"Розгорнути дозвіл \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\""</string>
<string name="permission_collapse" msgid="3320833884220844084">"Згорнути дозвіл \"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>\""</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 6d3682507e34..9cf41cfba539 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"ساتھی آلہ مینیجر"</string>
<string name="confirmation_title" msgid="4593465730772390351">"‏‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‎ کو ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎ تک رسائی کی اجازت دیں؟"</string>
<string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"‏‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‎ کے ذریعے منتخب کیے جانے کیلئے آلہ منتخب کریں"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"سیٹ اپ کرنے کے لیے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کا انتخاب کریں"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"اس ایپ کو آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر کسی کال کرنے والے کے نام جیسی معلومات کی مطابقت پذیری کرنے اور ان اجازتوں تک رسائی کی اجازت ہوگی"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; کا نظم کرنے کی اجازت دیں؟"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"آلہ"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"اس ایپ کو آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر ان اجازتوں تک رسائی کی اجازت ہوگی"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو اجازت دیں"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"یہ ایپ آپ کے فون اور منتخب کردہ آلے کے درمیان معلومات، جیسے کسی کال کرنے والے کے نام، کی مطابقت پذیری کر سکے گی"</string>
<string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
<string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"منسوخ کریں"</string>
<string name="consent_back" msgid="2560683030046918882">"پیچھے"</string>
<string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> کو پھیلائیں"</string>
<string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> کو سکیڑیں"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 569c62dc3381..42dcd7289805 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
<string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"soat"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; boshqaradigan qurilmani tanlang"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Sozlash uchun <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilini tanlang"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Bu ilovaga chaqiruvchining ismi kabi maʼlumotlarni sinxronlash va <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasida quyidagi amallarni bajarishga ruxsat beriladi"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasini boshqarish uchun ruxsat berilsinmi?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"qurilma"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasida quyidagi ruxsatlarni oladi"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Bu ilova telefoningiz va tanlangan qurilmada chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi"</string>
<string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Bekor qilish"</string>
<string name="consent_back" msgid="2560683030046918882">"Orqaga"</string>
<string name="permission_expand" msgid="893185038020887411">"Yoyish: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Yopish: <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index cbe46a1f1438..51f69b232b3a 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Trình quản lý thiết bị đồng hành"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Chọn một thiết bị sẽ do &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; quản lý"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> để thiết lập"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Ứng dụng này sẽ được phép đồng bộ hoá thông tin (chẳng hạn như tên của người đang gọi điện) và dùng những quyền sau trên <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; quản lý &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"thiết bị"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Ứng dụng này sẽ được phép dùng những quyền sau trên <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Ứng dụng này sẽ đồng bộ hoá thông tin (ví dụ: tên người gọi) giữa điện thoại của bạn và thiết bị bạn chọn"</string>
<string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
<string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Huỷ"</string>
<string name="consent_back" msgid="2560683030046918882">"Quay lại"</string>
<string name="permission_expand" msgid="893185038020887411">"Mở rộng <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Thu gọn <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 0dabb5486694..578302b74eff 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"配套设备管理器"</string>
<string name="confirmation_title" msgid="4593465730772390351">"允许&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;访问&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手表"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"选择要由&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;管理的设备"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"选择 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 进行设置"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"该应用将可以同步信息(例如来电者的姓名),并可以获得您<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的以下权限"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"允许&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;管理&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"设备"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"该应用将可以获得您<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的以下权限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;strong&gt;&lt;/strong&gt;访问您手机中的这项信息"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"此应用将能在您的手机和所选设备之间同步信息,例如来电者的姓名"</string>
<string name="consent_yes" msgid="8344487259618762872">"允许"</string>
<string name="consent_no" msgid="2640796915611404382">"不允许"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_expand" msgid="893185038020887411">"展开<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收起<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 31aa0e99d2b4..22694eb3d67a 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
<string name="confirmation_title" msgid="4593465730772390351">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;嗎?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"選擇要讓 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 管理的裝置"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"選擇要設定的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"此應用程式將可同步資訊 (例如來電者的名稱),並可在<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上取得以下權限"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;嗎?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"此應用程式將可在<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上取得以下權限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資料"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求權限,以便在裝置間串流應用程式的內容"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"此應用程式將可同步手機和所選裝置的資訊,例如來電者的名稱"</string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_expand" msgid="893185038020887411">"展開<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收合<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 61d4a2e8aa29..a8151ded0588 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
<string name="confirmation_title" msgid="4593465730772390351">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;嗎?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"選擇要讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理的裝置"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"選擇要設定的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"這個應用程式將可同步處理資訊 (例如來電者名稱)、取得<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的這些權限"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;嗎?"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"這個應用程式將可取得<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的這些權限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取手機中的這項資訊"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"為了在裝置間串流傳輸應用程式內容,「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求相關權限"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"這個應用程式將可在手機和指定裝置間同步資訊,例如來電者名稱"</string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"取消"</string>
<string name="consent_back" msgid="2560683030046918882">"返回"</string>
<string name="permission_expand" msgid="893185038020887411">"展開<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"收合<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index f87895c17fb9..d9b5c52492d4 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -19,17 +19,12 @@
<string name="app_label" msgid="4470785958457506021">"Isiphathi sedivayisi esihambisanayo"</string>
<string name="confirmation_title" msgid="4593465730772390351">"Vumela &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukufinyelela &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
<string name="profile_name_watch" msgid="576290739483672360">"buka"</string>
- <!-- no translation found for chooser_title_non_profile (6035023914517087400) -->
- <skip />
- <!-- no translation found for chooser_title (2235819929238267637) -->
- <skip />
- <!-- no translation found for summary_watch (7962014927042971830) -->
- <skip />
+ <string name="chooser_title_non_profile" msgid="6035023914517087400">"Khetha idivayisi engaphathwa nge-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
+ <string name="chooser_title" msgid="2235819929238267637">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ukusetha"</string>
+ <string name="summary_watch" msgid="7962014927042971830">"Le-app izovunyelwa ukuvumelanisa ulwazi, olufana negama lomuntu ofonayo, iphinde ifinyelele lezi zimvume ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho"</string>
<string name="confirmation_title_glasses" msgid="8288346850537727333">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuthi ifinyelele i-&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
- <!-- no translation found for profile_name_glasses (3506504967216601277) -->
- <skip />
- <!-- no translation found for summary_glasses (2872254734959842579) -->
- <skip />
+ <string name="profile_name_glasses" msgid="3506504967216601277">"idivayisi"</string>
+ <string name="summary_glasses" msgid="2872254734959842579">"Le-app izovunyelwa ukufinyelela lezi zimvume ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
@@ -45,8 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho nedivayisi ekhethiwe"</string>
<string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
<string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
- <!-- no translation found for consent_cancel (5655005528379285841) -->
- <skip />
+ <string name="consent_cancel" msgid="5655005528379285841">"Khansela"</string>
<string name="consent_back" msgid="2560683030046918882">"Emuva"</string>
<string name="permission_expand" msgid="893185038020887411">"Nweba i-<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Goqa i-<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index b2628fb4017c..475dcf796109 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -24,7 +24,7 @@
<string name="string_learn_more" msgid="4541600451688392447">"የበለጠ ለመረዳት"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"የይለፍ ቃል አሳይ"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"የይለፍ ቃል ደብቅ"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቃል ይበልጥ ደህንነቱ የተጠበቀ"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቁልፎች ይበልጥ ደህንነቱ የተጠበቀ"</string>
<string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"በይለፍ ቁልፎች ውስብስብ የይለፍ ቁልፎችን መፍጠር ወይም ማስታወስ አያስፈልግዎትም"</string>
<string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"የይለፍ ቁልፎች የእርስዎን የጣት አሻራ፣ መልክ ወይም የማያ ገፅ መቆለፊያ በመጠቀም የሚፈጥሯቸው የተመሰጠሩ ዲጂታል ቆልፎች ናቸው"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"በሌሎች መሣሪያዎች ላይ መግባት እንዲችሉ በሚስጥር ቁልፍ አስተዳዳሪ ላይ ይቀመጣሉ"</string>
diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml
index 209c9c2f6e34..d0f8bb0ba1c2 100644
--- a/packages/CredentialManager/res/values-az/strings.xml
+++ b/packages/CredentialManager/res/values-az/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Ətraflı məlumat"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Parolu göstərin"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Parolu gizlədin"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Giriş açarları ilə daha təhlükəsiz"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Giriş açarları ilə mürəkkəb parollar yaratmağa və ya yadda saxlamağa ehtiyac yoxdur"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Açarlar ilə daha təhlükəsiz"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Açarlar ilə mürəkkəb parollar yaratmağa və ya yadda saxlamağa ehtiyac yoxdur"</string>
<string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Giriş açarları barmaq izi, üz və ya ekran kilidindən istifadə edərək yaratdığınız şifrələnmiş rəqəmsal açarlardır"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Onlar parol menecerində saxlanılır ki, digər cihazlarda daxil ola biləsiniz"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Giriş açarları haqqında ətraflı"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Açarlar haqqında ətraflı"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsuz texnologiya"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Giriş açarları parollara etibar etmədən daxil olmağa imkan verir. Kimliyinizi doğrulamaq və giriş açarı yaratmaq üçün sadəcə barmaq izi, üz tanıma, PIN və ya sürüşdürmə modelindən istifadə etməlisiniz."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Giriş açarları parollara etibar etmədən daxil olmağa imkan verir. Kimliyinizi doğrulamaq və açar yaratmaq üçün sadəcə barmaq izi, üz tanıma, PIN və ya sürüşdürmə modelindən istifadə etməlisiniz."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"İctimai açar kriptoqrafiyası"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft və s. daxildir) və W3C standartlarına əsaslanaraq giriş açarları kriptoqrafik açar cütlərindən istifadə edir. İstifadəçi adı və parollar üçün istifadə etdiyimiz simvol sətrindən fərqli olaraq, tətbiq və ya vebsayt üçün şəxsi-ictimai açar cütü yaradılır. Şəxsi açar cihazınızda və ya parol menecerinizdə təhlükəsiz şəkildə saxlanılır və kimliyinizi təsdiq edir. İctimai açar tətbiq və ya vebsayt serveri ilə paylaşılır. Müvafiq açarlarla dərhal qeydiyyatdan keçə və daxil ola bilərsiniz."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft və s. daxildir) və W3C standartlarına əsaslanaraq açarlar kriptoqrafik açar cütlərindən istifadə edir. İstifadəçi adı və parollar üçün istifadə etdiyimiz simvol sətrindən fərqli olaraq, tətbiq və ya vebsayt üçün şəxsi-ictimai açar cütü yaradılır. Şəxsi açar cihazınızda və ya parol menecerinizdə təhlükəsiz şəkildə saxlanılır və kimliyinizi təsdiq edir. İctimai açar tətbiq və ya vebsayt serveri ilə paylaşılır. Müvafiq açarlarla dərhal qeydiyyatdan keçə və daxil ola bilərsiniz."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Təkmilləşdirilmiş hesab təhlükəsizliyi"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hər bir açar eksklüziv olaraq onların yaradıldığı tətbiq və ya vebsaytla əlaqələndirilib, ona görə də heç vaxt səhvən saxta tətbiqə və ya vebsayta daxil ola bilməzsiniz. Üstəlik, yalnız ictimai açarları saxlayan serverlərlə hekinq daha çətindir."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Rahat keçid"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də giriş açarları ilə yanaşı əlçatan olacaq."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də açarlar ilə yanaşı əlçatan olacaq."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş açarı yaradılsın?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string>
<string name="passkey" msgid="632353688396759522">"açar"</string>
<string name="password" msgid="6738570945182936667">"parol"</string>
- <string name="passkeys" msgid="5733880786866559847">"giriş açarları"</string>
+ <string name="passkeys" msgid="5733880786866559847">"açarlar"</string>
<string name="passwords" msgid="5419394230391253816">"parollar"</string>
<string name="sign_ins" msgid="4710739369149469208">"girişlər"</string>
<string name="sign_in_info" msgid="2627704710674232328">"Giriş məlumatları"</string>
@@ -53,13 +53,13 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Parol başqa cihazda yadda saxlansın?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Giriş başqa cihazda yadda saxlansın?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Bütün girişlər üçün <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> istifadə edilsin?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün bu parol meneceri asanlıqla daxil olmağınız məqsədilə parol və giriş açarlarını saxlayacaq"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün bu parol meneceri asanlıqla daxil olmağınız məqsədilə parol və açarları saxlayacaq"</string>
<string name="set_as_default" msgid="4415328591568654603">"Defolt olaraq seçin"</string>
<string name="settings" msgid="6536394145760913145">"Ayarlar"</string>
<string name="use_once" msgid="9027366575315399714">"Bir dəfə istifadə edin"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> giriş açarı"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> açar"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> giriş açarı"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> açarları"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> giriş məlumatları"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Giriş açarı"</string>
<string name="another_device" msgid="5147276802037801217">"Digər cihaz"</string>
diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml
index e60420a168d9..ef4dd54c59f1 100644
--- a/packages/CredentialManager/res/values-bg/strings.xml
+++ b/packages/CredentialManager/res/values-bg/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Научете повече"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Показване на паролата"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Скриване на паролата"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"По-сигурно с помощта на кодове за достъп"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Когато използвате кодове за достъп, не е необходимо да създавате, нито да помните сложни пароли"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Кодовете за достъп са шифровани дигитални ключове, които създавате посредством отпечатъка, лицето си или опцията си за заключване на екрана"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"По-сигурно с помощта на ключове за достъп"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Когато използвате ключове за достъп, не е необходимо да създавате, нито да помните сложни пароли"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ключовете за достъп са шифровани дигитални ключове, които създавате посредством отпечатъка, лицето си или опцията си за заключване на екрана"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Данните се запазват в мениджър на пароли, за да можете да влизате в профила си на други устройства"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Още за кодовете за достъп"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Още за ключовете за достъп"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Заменяща паролите технология"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Кодовете за достъп ви дават възможност да влизате в профила си без парола. Трябва само да използвате отпечатъка, лицето, ПИН кода или фигурата си, за да потвърдите самоличността си и да създадете код за достъп."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Ключовете за достъп ви дават възможност да влизате в профила си без парола. Трябва само да използвате отпечатъка, лицето, ПИН кода или фигурата си, за да потвърдите самоличността си и да създадете код за достъп."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптография с публичен ключ"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според съюза FIDO (Google, Apple, Microsoft и др.) и стандартите на W3C кодовете за достъп ползват двойки криптографски ключове. Вместо потребителско име и парола за дадено приложение или уебсайт се създава двойка ключове – частен и публичен. Първият се съхранява надеждно на устройството ви или в мениджъра на пароли и служи за потвърждаване на самоличността ви. Вторият се споделя със съответния сървър. С двойката ключове можете да се регистрирате и да влезете в профила си незабавно."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според съюза FIDO (Google, Apple, Microsoft и др.) и стандартите на W3C ключовете за достъп ползват двойки криптографски ключове. Вместо потребителско име и парола за дадено приложение или уебсайт се създава двойка ключове – частен и публичен. Първият се съхранява надеждно на устройството ви или в мениджъра на пароли и служи за потвърждаване на самоличността ви. Вторият се споделя със съответния сървър. С двойката ключове можете да се регистрирате и да влезете в профила си незабавно."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Подобрена сигурност на профила"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Всеки ключ е свързан само с приложението или уебсайта, за които е създаден. Затова не е възможно да влезете в измамно приложение или уебсайт по погрешка. Освен това сървърите съхраняват само публичните ключове, което значително затруднява опитите за хакерство."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Безпроблемен преход"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с кодовете за достъп по пътя ни към бъдеще без пароли."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с ключовете за достъп по пътя ни към бъдеще без пароли."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Изберете къде да запазите своите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Изберете мениджър на пароли, в който да се запазят данните ви, така че следващия път да влезете по-бързо в профила си"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се създаде ли код за достъп за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се запазят ли данните за вход за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
<string name="passkey" msgid="632353688396759522">"код за достъп"</string>
<string name="password" msgid="6738570945182936667">"парола"</string>
- <string name="passkeys" msgid="5733880786866559847">"кодове за достъп"</string>
+ <string name="passkeys" msgid="5733880786866559847">"ключове за достъп"</string>
<string name="passwords" msgid="5419394230391253816">"пароли"</string>
<string name="sign_ins" msgid="4710739369149469208">"данни за вход"</string>
<string name="sign_in_info" msgid="2627704710674232328">"данните за вход"</string>
@@ -53,13 +53,13 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Паролата да се запази ли на друго устройство?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Данните за вход да се запазят ли на друго устройство?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Да се използва ли <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> за всичките ви данни за вход?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Мениджърът на пароли за <xliff:g id="USERNAME">%1$s</xliff:g> ще съхранява вашите пароли и кодове за достъп, за да влизате лесно в профила си"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Мениджърът на пароли за <xliff:g id="USERNAME">%1$s</xliff:g> ще съхранява вашите пароли и ключове за достъп, за да влизате лесно в профила си"</string>
<string name="set_as_default" msgid="4415328591568654603">"Задаване като основно"</string>
<string name="settings" msgid="6536394145760913145">"Настройки"</string>
<string name="use_once" msgid="9027366575315399714">"Еднократно използване"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> кода за достъп"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ключа за достъп"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> кода за достъп"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ключа за достъп"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"Идентификационни данни: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Код за достъп"</string>
<string name="another_device" msgid="5147276802037801217">"Друго устройство"</string>
diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml
index d63b24fac89b..9fe5a492c8e7 100644
--- a/packages/CredentialManager/res/values-cs/strings.xml
+++ b/packages/CredentialManager/res/values-cs/strings.xml
@@ -32,7 +32,7 @@
<string name="passwordless_technology_title" msgid="2497513482056606668">"Technologie bez hesel"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"Přístupové klíče umožňují přihlašovat se bez hesel. Stačí pomocí otisku prstu, rozpoznání obličeje, kódu PIN nebo gesta ověřit svou totožnost a vytvořit přístupový klíč."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografie s veřejným klíčem"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Podle pokynů FIDO Alliance (která zahrnuje společnosti Google, Apple, Microsoft a další) a standardů W3C používají přístupové klíče páry kryptografických klíčů. Na rozdíl od uživatelského jména a řetězce znaků, které používáme pro hesla, se pro aplikaci nebo web vytváří pár klíčů (soukromého a veřejného). Soukromý klíč je bezpečně uložen ve vašem zařízení nebo správci hesel a potvrzuje vaši identitu. Veřejný klíč je sdílen s aplikací nebo webovým serverem. Pomocí odpovídajících klíčů se můžete okamžitě zaregistrovat a přihlásit."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Podle pokynů FIDO Alliance (zahrnující mj. firmy Google, Apple a Microsoft) a standardů W3C používají přístupové klíče páry kryptografických klíčů. Na rozdíl od jména uživatele a řetězce znaků používaného pro heslo se pro aplikaci nebo web vytváří soukromý a veřejný klíč. Soukromý klíč se bezpečně uloží do zařízení nebo správce hesel a potvrzuje vaši identitu. Veřejný klíč se sdílí s aplikací nebo webovým serverem. Pomocí odpovídajících klíčů se můžete rychle zaregistrovat a přihlásit."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Vylepšené zabezpečení účtu"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Každý klíč je propojen výhradně s aplikací nebo webem, pro které byl vytvořen, takže se nikdy nemůžete omylem přihlásit k podvodné aplikaci nebo webu. Protože na serverech jsou uloženy pouze veřejné klíče, je hackování navíc mnohem obtížnější."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Bezproblémový přechod"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index 3e72a11865c5..155be6fc90db 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -36,7 +36,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, les mots de passe seront toujours utilisés parallèlement aux clés d\'accès."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -75,7 +75,7 @@
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choisissez une clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Choisissez un mot de passe enregistré pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Choisissez une connexion enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Choisir un identifiant de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="get_dialog_title_choose_sign_in_for" msgid="3048870756117876514">"Choisissez un identifiant de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Choisir une option pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_title_use_info_on" msgid="8863708099535435146">"Utiliser ces renseignements dans <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Se connecter d\'une autre manière"</string>
diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml
index 9565e3191f45..4425e246398e 100644
--- a/packages/CredentialManager/res/values-hr/strings.xml
+++ b/packages/CredentialManager/res/values-hr/strings.xml
@@ -32,7 +32,7 @@
<string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija bez upotrebe zaporke"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"Pristupni ključevi omogućuju prijavu bez upotrebe zaporki. Treba vam samo otisak prsta, prepoznavanje lica, PIN ili uzorak pokreta prstom da biste potvrdili svoj identitet i izradili pristupni ključ."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografija javnog ključa"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Na temelju organizacije FIDO Alliance (koja uključuje Google, Apple, Microsoft i mnoge druge) i standarda W3C pristupni ključevi koriste kriptografske ključeve. Za razliku od korisničkog imena i niza znakova za zaporke, privatno-javni ključ izrađen je za aplikaciju ili web-lokaciju. Privatni ključ pohranjen je na vašem uređaju ili upravitelju zaporki i potvrđuje vaš identitet. Javni se ključ dijeli s poslužiteljem aplikacije ili web-lokacije. Uz odgovarajuće ključeve možete se odmah registrirati i prijaviti."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Prema standardima FIDO Alliancea (koja uključuje Google, Apple, Microsoft i mnoge druge) i W3C-a pristupni ključevi koriste kriptografske ključeve. Za razliku od korisničkog imena i niza znakova za zaporke, privatno-javni ključ izrađen je za aplikaciju ili web-lokaciju. Privatni ključ pohranjen je na vašem uređaju ili upravitelju zaporki i potvrđuje vaš identitet. Javni se ključ dijeli s poslužiteljem aplikacije ili web-lokacije. Uz odgovarajuće ključeve možete se odmah registrirati i prijaviti."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana sigurnost računa"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki je ključ povezan isključivo s aplikacijom ili web-lokacijom za koju je izrađen, stoga se nikad ne možete pogreškom prijaviti u prijevarnu aplikaciju ili na web-lokaciju. Osim toga, kad je riječ o poslužiteljima na kojem se nalaze samo javni ključevi, hakiranje je mnogo teže."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Besprijekorni prijelaz"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index 4ed616a1be4c..cb68444cc8bf 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string>
<string name="passkey" msgid="632353688396759522">"Кіру кілті"</string>
<string name="password" msgid="6738570945182936667">"құпия сөз"</string>
- <string name="passkeys" msgid="5733880786866559847">"Кіру кілттері"</string>
+ <string name="passkeys" msgid="5733880786866559847">"кіру кілттері"</string>
<string name="passwords" msgid="5419394230391253816">"Құпия сөздер"</string>
<string name="sign_ins" msgid="4710739369149469208">"кіру әрекеттері"</string>
<string name="sign_in_info" msgid="2627704710674232328">"кіру мәліметі"</string>
diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml
index af332e1b181f..b4c567077859 100644
--- a/packages/CredentialManager/res/values-ky/strings.xml
+++ b/packages/CredentialManager/res/values-ky/strings.xml
@@ -53,7 +53,7 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Сырсөздү башка түзмөктө сактайсызбы?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Кирүү маалыматын башка түзмөктө сактайсызбы?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> бардык аккаунттарга кирүү үчүн колдонулсунбу?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Сырсөздөрүңүздү жана ачкычтарыңызды <xliff:g id="USERNAME">%1$s</xliff:g> аккаунтуңуздагы сырсөздөрдү башкаргычка сактап коюп, каалаган убакта колдоно берсеңиз болот"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Сырсөздөрүңүздү жана киргизүүчү ачкычтарыңызды <xliff:g id="USERNAME">%1$s</xliff:g> аккаунтуңуздагы сырсөздөрдү башкаргычка сактап коюп, каалаган убакта колдоно берсеңиз болот"</string>
<string name="set_as_default" msgid="4415328591568654603">"Демейки катары коюу"</string>
<string name="settings" msgid="6536394145760913145">"Параметрлер"</string>
<string name="use_once" msgid="9027366575315399714">"Бир жолу колдонуу"</string>
diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml
index 173b2b16a8c4..d5f5f7f10578 100644
--- a/packages/CredentialManager/res/values-lt/strings.xml
+++ b/packages/CredentialManager/res/values-lt/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Sužinokite daugiau"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Rodyti slaptažodį"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Slėpti slaptažodį"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Saugiau naudojant slaptažodžius"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Naudojant „passkey“ nereikės kurti ir prisiminti sudėtingų slaptažodžių"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"„Passkey“ šifruojami skaitiniais raktais, kuriuos sukuriate naudodami piršto atspaudą, veidą ar ekrano užraktą"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Saugiau naudojant prieigos raktus"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Naudojant prieigos raktus nereikės kurti ir prisiminti sudėtingų slaptažodžių"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Prieigos raktai šifruojami skaitiniais raktais, kuriuos sukuriate naudodami piršto atspaudą, veidą ar ekrano užraktą"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Jie saugomi slaptažodžių tvarkyklėje, kad galėtumėte prisijungti kituose įrenginiuose"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Daugiau apie slaptuosius raktus („passkey“)"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Daugiau apie prieigos raktus („passkey“)"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Technologijos be slaptažodžių"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Naudodami slaptuosius raktus galite prisijungti be slaptažodžių. Tiesiog naudokite piršto atspaudą, atpažinimą pagal veidą, PIN kodą arba perbraukiamą atrakinimo piešinį, kad patvirtintumėte tapatybę ir sukurtumėte slaptąjį raktą."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Naudodami prieigos raktus galite prisijungti be slaptažodžių. Tiesiog naudokite piršto atspaudą, atpažinimą pagal veidą, PIN kodą arba perbraukiamą atrakinimo piešinį, kad patvirtintumėte tapatybę ir sukurtumėte prieigos raktą."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Viešojo rakto kriptografija"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Pagal FIDO aljansą (kuriam priklauso „Google“, „Apple“, „Microsoft“ ir kt.) bei W3C standartus, slaptiesiems raktams naudojamos kriptografinių raktų poros. Priešingai nei naudotojo vardas ir eilutė simbolių, naudojamų slaptažodžiams, privataus ir viešojo raktų pora sukuriama programai ar svetainei. Tapatybę patvirtinantis privatusis raktas saugomas įrenginyje ar Slaptažodžių tvarkyklėje. Viešasis raktas bendrinamas su programos ar svetainės serveriu. Naudodami atitinkamus raktus galite akimirksniu užsiregistruoti ir prisijungti."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Pagal FIDO aljansą (kuriam priklauso „Google“, „Apple“, „Microsoft“ ir kt.) bei W3C standartus, prieigos raktams naudojamos kriptografinių raktų poros. Priešingai nei naudotojo vardas ir eilutė simbolių, naudojamų slaptažodžiams, privataus ir viešojo raktų pora sukuriama programai ar svetainei. Tapatybę patvirtinantis privatusis raktas saugomas įrenginyje ar Slaptažodžių tvarkyklėje. Viešasis raktas bendrinamas su programos ar svetainės serveriu. Naudodami atitinkamus raktus galite akimirksniu užsiregistruoti ir prisijungti."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Geresnė paskyros sauga"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Kiekvienas raktas išskirtinai susietas su programa ar svetaine, kuriai buvo sukurtas, todėl niekada per klaidą neprisijungsite prie apgavikiškos programos ar svetainės. Be to, viešieji raktai laikomi tik serveriuose, todėl įsilaužti tampa gerokai sudėtingiau."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sklandus perėjimas"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su slaptaisiais raktais."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su prieigos raktais."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Pasirinkite, kur išsaugoti „<xliff:g id="CREATETYPES">%1$s</xliff:g>“"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Pasirinkite slaptažodžių tvarkyklę, kurią naudodami galėsite išsaugoti informaciją ir kitą kartą prisijungti greičiau"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sukurti „passkey“, skirtą „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Išsaugoti prisijungimo prie „<xliff:g id="APPNAME">%1$s</xliff:g>“ informaciją?"</string>
<string name="passkey" msgid="632353688396759522">"„passkey“"</string>
<string name="password" msgid="6738570945182936667">"slaptažodis"</string>
- <string name="passkeys" msgid="5733880786866559847">"passkey"</string>
+ <string name="passkeys" msgid="5733880786866559847">"prieigos raktas"</string>
<string name="passwords" msgid="5419394230391253816">"slaptažodžiai"</string>
<string name="sign_ins" msgid="4710739369149469208">"prisijungimo informacija"</string>
<string name="sign_in_info" msgid="2627704710674232328">"prisijungimo informaciją"</string>
@@ -53,13 +53,13 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Išsaugoti slaptažodį kitame įrenginyje?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Išsaugoti prisijungimo duomenis kitame įrenginyje?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Naudoti <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> visada prisijungiant?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir „passkey“, kad galėtumėte lengvai prisijungti"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir prieigos raktai, kad galėtumėte lengvai prisijungti"</string>
<string name="set_as_default" msgid="4415328591568654603">"Nustatyti kaip numatytąjį"</string>
<string name="settings" msgid="6536394145760913145">"Nustatymai"</string>
<string name="use_once" msgid="9027366575315399714">"Naudoti vieną kartą"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • „Passkey“: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Prieigos raktų: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"„passkey“: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Prieigos raktai: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"Prisijungimo duomenų: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Slaptažodis"</string>
<string name="another_device" msgid="5147276802037801217">"Kitas įrenginys"</string>
diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml
index 9bea6ac3652c..0755c9cdfa48 100644
--- a/packages/CredentialManager/res/values-mk/strings.xml
+++ b/packages/CredentialManager/res/values-mk/strings.xml
@@ -59,7 +59,7 @@
<string name="use_once" msgid="9027366575315399714">"Употребете еднаш"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Лозинки: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> лозинки"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> криптографски клучеви"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"Акредитиви: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Криптографски клуч"</string>
<string name="another_device" msgid="5147276802037801217">"Друг уред"</string>
diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml
index da87fcd426b4..b933f3e31bdb 100644
--- a/packages/CredentialManager/res/values-ms/strings.xml
+++ b/packages/CredentialManager/res/values-ms/strings.xml
@@ -36,7 +36,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Keselamatan akaun yang dipertingkatkan"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Setiap kunci dipautkan secara eksklusif dengan apl atau laman web kunci dicipta, jadi anda tidak boleh log masuk ke apl atau laman web penipuan secara tidak sengaja. Selain itu, dengan pelayan yang hanya menyimpan kunci awam, penggodaman menjadi jauh lebih sukar."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Peralihan yang lancar"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Semasa kita bergerak menuju ke arah masa depan tanpa kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Meskipun masa depan kita nanti tidak memerlukan kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat untuk menyimpan <xliff:g id="CREATETYPES">%1$s</xliff:g> anda"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Pilih Password Manager untuk menyimpan maklumat anda dan log masuk lebih pantas pada kali seterusnya"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Cipta kunci laluan untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -59,7 +59,7 @@
<string name="use_once" msgid="9027366575315399714">"Gunakan sekali"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> kata laluan • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> kunci laluan"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"Kata laluan <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Kunci laluan <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> kunci laluan"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> bukti kelayakan"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Kunci laluan"</string>
<string name="another_device" msgid="5147276802037801217">"Peranti lain"</string>
diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml
index a041c81be5ea..33b0b3ae4336 100644
--- a/packages/CredentialManager/res/values-nb/strings.xml
+++ b/packages/CredentialManager/res/values-nb/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Finn ut mer"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Vis passordet"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Skjul passordet"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Tryggere med tilgangsnøkler"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med tilgangsnøkler trenger du ikke å lage eller huske kompliserte passord"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Tilgangsnøkler er krypterte digitale nøkler du oppretter med fingeravtrykket, ansiktet eller skjermlåsen"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Tryggere med passnøkler"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med passnøkler trenger du ikke å lage eller huske kompliserte passord"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passnøkler er krypterte digitale nøkler du oppretter med fingeravtrykket, ansiktet eller skjermlåsen"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"De lagres i et verktøy for passordlagring, slik at du kan logge på andre enheter"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om tilgangsnøkler"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om passnøkler"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Passordfri teknologi"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Med tilgangsnøkler kan du logge på uten å bruke passord. Du trenger bare å bruke et fingeravtrykk, ansiktsgjenkjenning, en PIN-kode eller et sveipemønster for å bekrefte hvem du er, og lage en tilgangsnøkkel."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Med passnøkler kan du logge på uten å bruke passord. Du trenger bare å bruke et fingeravtrykk, ansiktsgjenkjenning, en PIN-kode eller et sveipemønster for å bekrefte hvem du er, og lage en passnøkkel."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografi for offentlige nøkler"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Tilgangsnøkler er basert på FIDO Alliance (med bl.a. Google, Apple og Microsoft) og W3C-standardene og bruker kryptografiske nøkkelpar. I stedet for brukernavn og strenger med tegn som brukes som passord, opprettes det et privat-offentlig nøkkelpar per app eller nettsted. Den private nøkkelen lagres trygt på enheten eller i passordlagringen og bekrefter hvem du er. Den offentlige nøkkelen deles med app- eller nettstedstjeneren. Med korresponderende nøkler kan du raskt registrere deg og logge på."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Passnøkler er basert på FIDO Alliance (med bl.a. Google, Apple og Microsoft) og W3C-standardene og bruker kryptografiske nøkkelpar. I stedet for brukernavn og strenger med tegn som brukes som passord, opprettes det et privat-offentlig nøkkelpar per app eller nettsted. Den private nøkkelen lagres trygt på enheten eller i passordlagringen og bekrefter hvem du er. Den offentlige nøkkelen deles med app- eller nettstedstjeneren. Med korresponderende nøkler kan du raskt registrere deg og logge på."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhet"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøkkel er eksklusivt tilknyttet appen eller nettstedet den er laget for. Dermed kan du aldri logge på falske apper eller nettsteder ved et uhell. Og siden tjenerne bare har offentlige nøkler, blir det mye vanskeligere å hacke deg."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sømløs overgang"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av tilgangsnøkler."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av passnøkler."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du opprette en tilgangsnøkkel for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du lagre påloggingsinformasjon for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
<string name="passkey" msgid="632353688396759522">"tilgangsnøkkel"</string>
<string name="password" msgid="6738570945182936667">"passord"</string>
- <string name="passkeys" msgid="5733880786866559847">"tilgangsnøkler"</string>
+ <string name="passkeys" msgid="5733880786866559847">"passnøkler"</string>
<string name="passwords" msgid="5419394230391253816">"passord"</string>
<string name="sign_ins" msgid="4710739369149469208">"pålogginger"</string>
<string name="sign_in_info" msgid="2627704710674232328">"påloggingsinformasjon"</string>
@@ -53,13 +53,13 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Vil du lagre passordet på en annen enhet?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Vil du lagre pålogging på en annen enhet?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vil du bruke <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> for alle pålogginger?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Dette verktøyet for passordlagring for <xliff:g id="USERNAME">%1$s</xliff:g> lagrer passord og tilgangsnøkler, så det blir lett å logge på"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Dette verktøyet for passordlagring for <xliff:g id="USERNAME">%1$s</xliff:g> lagrer passord og passnøkler, så det blir lett å logge på"</string>
<string name="set_as_default" msgid="4415328591568654603">"Angi som standard"</string>
<string name="settings" msgid="6536394145760913145">"Innstillinger"</string>
<string name="use_once" msgid="9027366575315399714">"Bruk én gang"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> tilgangsnøkler"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> passnøkler"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> tilgangsnøkler"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> passnøkler"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>-legitimasjon"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Tilgangsnøkkel"</string>
<string name="another_device" msgid="5147276802037801217">"En annen enhet"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 5670dcbc9ba7..150ef0bc77ed 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -36,7 +36,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ଉନ୍ନତ ଆକାଉଣ୍ଟ ସୁରକ୍ଷା"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ପ୍ରତ୍ୟେକ କୀ\'କୁ ସେହି ଆପ କିମ୍ବା ୱେବସାଇଟ ସହ ଏକ୍ସକ୍ଲୁସିଭ ଭାବେ ଲିଙ୍କ କରାଯାଏ ଯେଉଁଥିପାଇଁ ଏହାକୁ ତିଆରି କରାଯାଇଛି, ଫଳରେ ଆପଣ ଭୁଲବଶତଃ କୌଣସି ପ୍ରତାରଣାମୂଳକ ଆପ କିମ୍ବା ୱେବସାଇଟରେ କେବେ ବି ସାଇନ ଇନ କରିପାରିବେ ନାହିଁ। ଏହା ସହ, କେବଳ ସର୍ଭରଗୁଡ଼ିକ ସାର୍ବଜନୀନ କୀ ରଖୁଥିବା ଯୋଗୁଁ ଏହାକୁ ହେକ କରିବା ବହୁତ କଷ୍ଟକର।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ବାଧାରହିତ ଟ୍ରାଞ୍ଜିସନ"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡ ବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string>
<string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g> କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସକୀ ତିଆରି କରିବେ?"</string>
diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml
index 5a838ae9ce25..93459e64779a 100644
--- a/packages/CredentialManager/res/values-pt-rBR/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml
@@ -26,7 +26,7 @@
<string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar senha"</string>
<string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string>
<string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela."</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string>
<string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string>
diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml
index 5a838ae9ce25..93459e64779a 100644
--- a/packages/CredentialManager/res/values-pt/strings.xml
+++ b/packages/CredentialManager/res/values-pt/strings.xml
@@ -26,7 +26,7 @@
<string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar senha"</string>
<string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string>
<string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela."</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string>
<string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string>
diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml
index c0a9064eea01..16ba2223cd4c 100644
--- a/packages/CredentialManager/res/values-sl/strings.xml
+++ b/packages/CredentialManager/res/values-sl/strings.xml
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
<string name="passkey" msgid="632353688396759522">"ključ za dostop"</string>
<string name="password" msgid="6738570945182936667">"geslo"</string>
- <string name="passkeys" msgid="5733880786866559847">"ključev za dostop"</string>
+ <string name="passkeys" msgid="5733880786866559847">"ključi za dostop"</string>
<string name="passwords" msgid="5419394230391253816">"gesel"</string>
<string name="sign_ins" msgid="4710739369149469208">"prijave"</string>
<string name="sign_in_info" msgid="2627704710674232328">"podatkov za prijavo"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index d70cf4dcffa1..40f8dc48c5d5 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -26,7 +26,7 @@
<string name="content_description_hide_password" msgid="6841375971631767996">"Fshih fjalëkalimin"</string>
<string name="passkey_creation_intro_title" msgid="4251037543787718844">"Më e sigurt me çelësat e kalimit"</string>
<string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Me çelësat e kalimit, nuk ka nevojë të krijosh ose të mbash mend fjalëkalime të ndërlikuara"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Çelësat e kalimit kanë çelësa dixhitalë të enkriptuar që ti i krijon duke përdorur gjurmën e gishtit, fytyrën ose kyçjen e ekranit"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Çelësat e kalimit janë çelësa dixhitalë të enkriptuar që ti i krijon duke përdorur gjurmën e gishtit, fytyrën ose kyçjen e ekranit"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ata ruhen te një menaxher fjalëkalimesh, në mënyrë që të mund të identifikohesh në pajisje të tjera"</string>
<string name="more_about_passkeys_title" msgid="7797903098728837795">"Më shumë rreth çelësave të kalimit"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Teknologji pa fjalëkalime"</string>
diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml
index 56e743daa351..ffb4fa0d307e 100644
--- a/packages/CredentialManager/res/values-sw/strings.xml
+++ b/packages/CredentialManager/res/values-sw/strings.xml
@@ -57,7 +57,7 @@
<string name="set_as_default" msgid="4415328591568654603">"Weka iwe chaguomsingi"</string>
<string name="settings" msgid="6536394145760913145">"Mipangilio"</string>
<string name="use_once" msgid="9027366575315399714">"Tumia mara moja"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • funguo <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> za siri"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Funguo <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> za siri"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
<string name="more_options_usage_passkeys" msgid="5390320437243042237">"Funguo <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> za siri"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"Kitambulisho cha <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml
index 6cd134d06e7f..e33f1bf3e283 100644
--- a/packages/CredentialManager/res/values-tl/strings.xml
+++ b/packages/CredentialManager/res/values-tl/strings.xml
@@ -32,7 +32,7 @@
<string name="passwordless_technology_title" msgid="2497513482056606668">"Teknolohiyang hindi gumagamit ng password"</string>
<string name="passwordless_technology_detail" msgid="6853928846532955882">"Sa pamamagitan ng mga passkey, makakapag-sign in ka nang hindi umaasa sa mga password. Kailangan mo lang gamitin ang iyong fingerprint, pagkilala ng mukha, PIN, o swipe pattern para i-verify ang pagkakakilanlan mo at gumawa ng passkey."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptography ng pampublikong key"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Batay sa FIDO Alliance (na kinabibilangan ng Google, Apple, Microsoft, atbp) at W3C standards, gumagamit ang passkeys ng cryptographic key pairs. Hindi tulad ng username at string ng characters na ginagamit sa password, para sa app o website ginagawa ang private-public key pair. Ligtas na naka-store sa device o password manager ang private key at kinukumpirma nito ang identity. Naka-share sa app o website server ang public key. Gamit ang key, instant kang makakapag-register at makakapag-sign in."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Batay sa FIDO Alliance (na kinabibilangan ng Google, Apple, Microsoft, atbp) at W3C standards, gumagamit ang mga passkey ng cryptographic key pairs. Hindi tulad ng username at string ng characters na ginagamit sa password, para sa app o website ginagawa ang private-public key pair. Ligtas na naka-store sa device o password manager ang private key at kinukumpirma nito ang identity. Naka-share sa app o website server ang public key. Gamit ang key, instant kang makakapag-register at makakapag-sign in."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Pinahusay na seguridad sa account"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Eksklusibong naka-link sa app o website kung para saan ginawa ang bawat key, kaya hindi ka makakapag-sign in sa isang mapanlokong app o website nang hindi sinasadya. Bukod pa rito, dahil mga pampublikong key lang ang itinatabi ng mga server, lubos na mas mahirap ang pag-hack."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Madaling transition"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index a3b72d57d250..30d1773cfb38 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Daha fazla bilgi"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Şifreyi göster"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Şifreyi gizle"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Şifre anahtarlarıyla daha yüksek güvenlik"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Şifre anahtarı kullandığınızda karmaşık şifreler oluşturmanız veya bunları hatırlamanız gerekmez"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Şifre anahtarları; parmak iziniz, yüzünüz veya ekran kilidinizi kullanarak oluşturduğunuz şifrelenmiş dijital anahtarlardır"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Geçiş anahtarlarıyla daha yüksek güvenlik"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Geçiş anahtarı kullandığınızda karmaşık şifreler oluşturmanız veya bunları hatırlamanız gerekmez"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Geçiş anahtarları; parmak iziniz, yüzünüz veya ekran kilidinizi kullanarak oluşturduğunuz şifrelenmiş dijital anahtarlardır"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Diğer cihazlarda oturum açabilmeniz için şifre anahtarları bir şifre yöneticisine kaydedilir"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Şifre anahtarları hakkında daha fazla bilgi"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Geçiş anahtarları hakkında daha fazla bilgi"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Şifresiz teknoloji"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Şifre anahtarları, şifre kullanmadan oturum açmanıza olanak tanır. Kimliğinizi doğrulayıp şifre anahtarı oluşturmak için parmak iziniz, yüz tanıma özelliği, PIN veya kaydırma deseni kullanmanız yeterlidir."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Geçiş anahtarları, şifre kullanmadan oturum açmanıza olanak tanır. Kimliğinizi doğrulayıp geçiş anahtarı oluşturmak için parmak iziniz, yüz tanıma özelliği, PIN veya kaydırma deseni kullanmanız yeterlidir."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Ortak anahtar kriptografisi"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Şifre anahtarları, FIDO Alliance (Google, Apple, Microsoft ve daha pek çok şirket yer alır) ve W3C standartları uyarınca şifreleme anahtarı çiftleri kullanır. Şifrelerde kullandığımız kullanıcı adı ve karakter dizisinden farklı olarak bir uygulama veya web sitesi için özel-ortak anahtar çifti oluşturulur. Özel anahtar, cihazınızda ya da şifre yöneticinizde güvenle saklanır ve kimliğinizi doğrular. Ortak anahtar, uygulama veya web sitesi sunucusuyla paylaşılır. İlgili anahtarları kullanarak anında kaydolabilir ve oturum açabilirsiniz."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Geçiş anahtarları, FIDO Alliance (Google, Apple, Microsoft ve daha pek çok şirket yer alır) ve W3C standartları uyarınca şifreleme anahtarı çiftleri kullanır. Şifrelerde kullandığımız kullanıcı adı ve karakter dizisinden farklı olarak bir uygulama veya web sitesi için özel-ortak anahtar çifti oluşturulur. Özel anahtar, cihazınızda ya da şifre yöneticinizde güvenle saklanır ve kimliğinizi doğrular. Ortak anahtar, uygulama veya web sitesi sunucusuyla paylaşılır. İlgili anahtarları kullanarak anında kaydolabilir ve oturum açabilirsiniz."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Daha iyi hesap güvenliği"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Her anahtar, oluşturulduğu uygulama veya web sitesiyle özel olarak bağlantılı olduğu için sahte bir uygulamaya veya web sitesine hiçbir zaman yanlışlıkla giriş yapamazsınız. Ayrıca, sunucularda yalnızca ortak anahtarlar saklandığı için saldırıya uğramak daha zordur."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sorunsuz geçiş"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, şifre anahtarlarıyla birlikte kullanılmaya devam edecektir."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, geçiş anahtarlarıyla birlikte kullanılmaya devam edecektir."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> için şifre anahtarı oluşturulsun mu?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string>
<string name="passkey" msgid="632353688396759522">"Şifre anahtarı"</string>
<string name="password" msgid="6738570945182936667">"Şifre"</string>
- <string name="passkeys" msgid="5733880786866559847">"Şifre anahtarlarınızın"</string>
+ <string name="passkeys" msgid="5733880786866559847">"Geçiş anahtarlarınızın"</string>
<string name="passwords" msgid="5419394230391253816">"şifreler"</string>
<string name="sign_ins" msgid="4710739369149469208">"oturum aç"</string>
<string name="sign_in_info" msgid="2627704710674232328">"Oturum açma bilgileri"</string>
@@ -53,13 +53,13 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Şifre başka bir cihaza kaydedilsin mi?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Oturum açma bilgileri başka bir cihaza kaydedilsin mi?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Tüm oturum açma işlemlerinizde <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kullanılsın mı?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> için bu şifre yöneticisi, şifrelerinizi ve şifre anahtarlarınızı saklayarak kolayca oturum açmanıza yardımcı olur"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> için bu şifre yöneticisi, şifrelerinizi ve geçiş anahtarlarınızı saklayarak kolayca oturum açmanıza yardımcı olur"</string>
<string name="set_as_default" msgid="4415328591568654603">"Varsayılan olarak ayarla"</string>
<string name="settings" msgid="6536394145760913145">"Ayarlar"</string>
<string name="use_once" msgid="9027366575315399714">"Bir kez kullanın"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> şifre anahtarı"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> geçiş anahtarı"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> şifre anahtarı"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> geçiş anahtarı"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> kimlik bilgileri"</string>
<string name="passkey_before_subtitle" msgid="2448119456208647444">"Şifre anahtarı"</string>
<string name="another_device" msgid="5147276802037801217">"Başka bir cihaz"</string>
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 5797121d2c45..a0785b615556 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -25,18 +25,18 @@
<string name="content_description_show_password" msgid="3283502010388521607">"Parolni koʻrsatish"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Parolni berkitish"</string>
<string name="passkey_creation_intro_title" msgid="4251037543787718844">"Kalitlar orqali qulay"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kodlar yordami tufayli murakkab parollarni yaratish va eslab qolish shart emas"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kodlar – bu barmoq izi, yuz yoki ekran qulfi yordamida yaratilgan shifrlangan raqamli identifikator."</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kalitlar yordami tufayli murakkab parollarni yaratish va eslab qolish shart emas"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kalitlar – bu barmoq izi, yuz yoki ekran qulfi yordamida yaratilgan shifrlangan raqamli identifikator."</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ular parollar menejerida saqlanadi va ulardan boshqa qurilmalarda hisobga kirib foydalanish mumkin"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Kodlar haqida batafsil"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Kalitlar haqida batafsil"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsiz texnologiya"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kodlar parollarga tayanmasdan tizimga kirish imkonini beradi. Shaxsingizni tasdiqlash va kod yaratish uchun barmoq izi, yuzni tanish, PIN kod yoki grafik kalitni surishdan foydalanishingiz kifoya."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kalitlar tizimga parol ishlatmasdan kirish imkonini beradi. Shaxsingizni tasdiqlash va kod yaratish uchun barmoq izi, yuzni tanish, PIN kod yoki grafik kalitni surishdan foydalanishingiz kifoya."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Ochiq kalit kriptografiyasi"</string>
<string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft va boshqalar) va W3C standartlari asosida kodlar kriptografik kalitlar juftligidan foydalanadi. Parollarda ishlatiladigan foydalanuvchi nomi va belgilardan farqli ravishda, ilova yoki veb-sayt uchun maxfiy ochiq kalitlar juftligi yaratiladi. Maxfiy kalit qurilmangizda yoki parollar menejerida xavfsiz saqlanadi va u shaxsingizni tasdiqlaydi. Ochiq kalit ilova yoki veb-sayt serveriga ulashiladi. Mos kalitlar bilan darhol registratsiya va tizimga kirish mumkin."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Hisob xavfsizligi yaxshilandi"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Har bir kalit faqat ular uchun yaratilgan ilova yoki veb-sayt bilan ulangan, shuning uchun siz hech qachon xatolik bilan soxta ilova yoki veb-saytga kira olmaysiz. Shuningdek, serverlar bilan faqat ochiq kalitlarni saqlagan holda, buzib kirish ancha qiyinroq boʻladi."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Uzluksiz oʻtish"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari borayotganimizda, parollar kodlar bilan birga ishlatilishda davom etadi."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari harakatlanar ekanmiz, parollar kalitlar bilan birga ishlatilishda davom etadi."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Bu <xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kod yaratilsinmi?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string>
<string name="passkey" msgid="632353688396759522">"kalit"</string>
<string name="password" msgid="6738570945182936667">"parol"</string>
- <string name="passkeys" msgid="5733880786866559847">"kodlar"</string>
+ <string name="passkeys" msgid="5733880786866559847">"kalitlar"</string>
<string name="passwords" msgid="5419394230391253816">"parollar"</string>
<string name="sign_ins" msgid="4710739369149469208">"kirishlar"</string>
<string name="sign_in_info" msgid="2627704710674232328">"kirish maʼlumoti"</string>
@@ -57,7 +57,7 @@
<string name="set_as_default" msgid="4415328591568654603">"Birlamchi deb belgilash"</string>
<string name="settings" msgid="6536394145760913145">"Sozlamalar"</string>
<string name="use_once" msgid="9027366575315399714">"Bir marta ishlatish"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ta kod"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ta kalit"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol"</string>
<string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ta kalit"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> hisobi maʼlumotlari"</string>
diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml
index 67b0e887deac..0e170254ab4b 100644
--- a/packages/CredentialManager/res/values-vi/strings.xml
+++ b/packages/CredentialManager/res/values-vi/strings.xml
@@ -24,19 +24,19 @@
<string name="string_learn_more" msgid="4541600451688392447">"Tìm hiểu thêm"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Hiện mật khẩu"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Ẩn mật khẩu"</string>
- <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ khoá đăng nhập"</string>
- <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Mã xác thực giúp bạn tránh được việc phải tạo và ghi nhớ mật khẩu phức tạp"</string>
- <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Mã xác thực là các khoá kỹ thuật số được mã hoá mà bạn tạo bằng cách dùng vân tay, khuôn mặt hoặc phương thức khoá màn hình của mình"</string>
+ <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ khoá truy cập"</string>
+ <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Khoá truy cập giúp bạn tránh được việc phải tạo và ghi nhớ mật khẩu phức tạp"</string>
+ <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Khoá truy cập là các khoá kỹ thuật số được mã hoá mà bạn tạo bằng cách dùng vân tay, khuôn mặt hoặc phương thức khoá màn hình của mình"</string>
<string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Thông tin này được lưu vào trình quản lý mật khẩu nên bạn có thể đăng nhập trên các thiết bị khác"</string>
- <string name="more_about_passkeys_title" msgid="7797903098728837795">"Xem thêm thông tin về khoá đăng nhập"</string>
+ <string name="more_about_passkeys_title" msgid="7797903098728837795">"Xem thêm thông tin về khoá truy cập"</string>
<string name="passwordless_technology_title" msgid="2497513482056606668">"Công nghệ không dùng mật khẩu"</string>
- <string name="passwordless_technology_detail" msgid="6853928846532955882">"Khoá đăng nhập cho phép bạn đăng nhập mà không cần dựa vào mật khẩu. Bạn chỉ cần dùng vân tay, tính năng nhận dạng khuôn mặt, mã PIN hoặc hình mở khoá để xác minh danh tính và tạo khoá đăng nhập."</string>
+ <string name="passwordless_technology_detail" msgid="6853928846532955882">"Khoá truy cập cho phép bạn đăng nhập mà không cần dựa vào mật khẩu. Bạn chỉ cần dùng vân tay, tính năng nhận dạng khuôn mặt, mã PIN hoặc hình mở khoá để xác minh danh tính và tạo khoá truy cập."</string>
<string name="public_key_cryptography_title" msgid="6751970819265298039">"Mã hoá khoá công khai"</string>
- <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Dựa trên Liên minh FIDO (bao gồm Google, Apple, Microsoft, v.v.) và tiêu chuẩn W3C, khoá đăng nhập sử dụng cặp khoá mã hoá. Khác với tên người dùng và chuỗi ký tự chúng tôi dùng cho mật khẩu, một cặp khoá riêng tư – công khai được tạo cho một ứng dụng hoặc trang web. Khoá riêng tư được lưu trữ an toàn trên thiết bị hoặc trình quản lý mật khẩu và xác nhận danh tính của bạn. Khoá công khai được chia sẻ với máy chủ ứng dụng hoặc trang web. Với khoá tương ứng, bạn có thể đăng ký và đăng nhập tức thì."</string>
+ <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Dựa trên Liên minh FIDO (bao gồm Google, Apple, Microsoft, v.v.) và tiêu chuẩn W3C, khoá truy cập sử dụng cặp khoá mã hoá. Khác với tên người dùng và chuỗi ký tự chúng tôi dùng cho mật khẩu, một cặp khoá riêng tư – công khai được tạo cho một ứng dụng hoặc trang web. Khoá riêng tư được lưu trữ an toàn trên thiết bị hoặc trình quản lý mật khẩu và xác nhận danh tính của bạn. Khoá công khai được chia sẻ với máy chủ ứng dụng hoặc trang web. Với khoá tương ứng, bạn có thể đăng ký và đăng nhập tức thì."</string>
<string name="improved_account_security_title" msgid="1069841917893513424">"Cải thiện tính bảo mật của tài khoản"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Mỗi khoá được liên kết riêng với ứng dụng hoặc trang web mà khoá đó được tạo. Vì vậy, bạn sẽ không bao giờ đăng nhập nhầm vào một ứng dụng hoặc trang web lừa đảo. Ngoài ra, với các máy chủ chỉ lưu giữ khoá công khai, việc xâm nhập càng khó hơn nhiều."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Chuyển đổi liền mạch"</string>
- <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá đăng nhập."</string>
+ <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá truy cập."</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn vào lần tới"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Tạo khoá đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
<string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Lưu thông tin đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
<string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string>
<string name="password" msgid="6738570945182936667">"mật khẩu"</string>
- <string name="passkeys" msgid="5733880786866559847">"khoá đăng nhập"</string>
+ <string name="passkeys" msgid="5733880786866559847">"khoá truy cập"</string>
<string name="passwords" msgid="5419394230391253816">"mật khẩu"</string>
<string name="sign_ins" msgid="4710739369149469208">"thông tin đăng nhập"</string>
<string name="sign_in_info" msgid="2627704710674232328">"thông tin đăng nhập"</string>
@@ -53,15 +53,15 @@
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Lưu mật khẩu trên một thiết bị khác?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Lưu thông tin đăng nhập trên một thiết bị khác?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Dùng <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> cho mọi thông tin đăng nhập của bạn?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Trình quản lý mật khẩu này cho <xliff:g id="USERNAME">%1$s</xliff:g> sẽ lưu trữ mật khẩu và khoá đăng nhập để bạn dễ dàng đăng nhập"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Trình quản lý mật khẩu này cho <xliff:g id="USERNAME">%1$s</xliff:g> sẽ lưu trữ mật khẩu và khoá truy cập để bạn dễ dàng đăng nhập"</string>
<string name="set_as_default" msgid="4415328591568654603">"Đặt làm mặc định"</string>
<string name="settings" msgid="6536394145760913145">"Cài đặt"</string>
<string name="use_once" msgid="9027366575315399714">"Dùng một lần"</string>
- <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> khoá đăng nhập"</string>
+ <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> khoá truy cập"</string>
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu"</string>
- <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> khoá đăng nhập"</string>
+ <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> khoá truy cập"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> thông tin xác thực"</string>
- <string name="passkey_before_subtitle" msgid="2448119456208647444">"Mã xác thực"</string>
+ <string name="passkey_before_subtitle" msgid="2448119456208647444">"Khoá truy cập"</string>
<string name="another_device" msgid="5147276802037801217">"Thiết bị khác"</string>
<string name="other_password_manager" msgid="565790221427004141">"Trình quản lý mật khẩu khác"</string>
<string name="close_sheet" msgid="1393792015338908262">"Đóng trang tính"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
index 7b17cbdd3a1e..19d74b33e034 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
@@ -16,6 +16,8 @@
package com.android.packageinstaller;
+import static android.content.Intent.CATEGORY_LAUNCHER;
+
import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID;
import android.app.Activity;
@@ -45,6 +47,9 @@ public class DeleteStagedFileOnResult extends Activity {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
setResult(resultCode, data);
finish();
+ if (data != null && data.hasCategory(CATEGORY_LAUNCHER)) {
+ startActivity(data);
+ }
}
@Override
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
index 73c03a57cade..ff991d2f7ee3 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
@@ -17,7 +17,6 @@
package com.android.packageinstaller;
import android.app.Activity;
-import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -123,11 +122,7 @@ public class InstallSuccess extends AlertActivity {
Button launchButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
if (enabled) {
launchButton.setOnClickListener(view -> {
- try {
- startActivity(mLaunchIntent);
- } catch (ActivityNotFoundException | SecurityException e) {
- Log.e(LOG_TAG, "Could not start activity", e);
- }
+ setResult(Activity.RESULT_OK, mLaunchIntent);
finish();
});
} else {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index d1541569bc55..e071c111d617 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -16,8 +16,9 @@
*/
package com.android.packageinstaller;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
-import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
+import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import android.Manifest;
@@ -789,7 +790,8 @@ public class PackageInstallerActivity extends AlertActivity {
}
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (!isDestroyed()) {
- startActivity(getIntent().addFlags(FLAG_ACTIVITY_REORDER_TO_FRONT));
+ startActivity(getIntent().addFlags(
+ FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP));
}
}, 500);
diff --git a/packages/PrintSpooler/res/values-mk/strings.xml b/packages/PrintSpooler/res/values-mk/strings.xml
index d96330c43daf..f4802556a439 100644
--- a/packages/PrintSpooler/res/values-mk/strings.xml
+++ b/packages/PrintSpooler/res/values-mk/strings.xml
@@ -46,7 +46,7 @@
<string name="print_button" msgid="645164566271246268">"Печати"</string>
<string name="savetopdf_button" msgid="2976186791686924743">"Зачувај во PDF"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"Опциите на печатачот се прикажани"</string>
- <string name="print_options_collapsed" msgid="7455930445670414332">"Опциите на печатачот се сокриени"</string>
+ <string name="print_options_collapsed" msgid="7455930445670414332">"Опциите на печатачот се скриени"</string>
<string name="search" msgid="5421724265322228497">"Пребарај"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Сите печатачи"</string>
<string name="add_print_service_label" msgid="5356702546188981940">"Додајте услуга"</string>
diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml
index be7af70a8752..13c3886460cd 100644
--- a/packages/PrintSpooler/res/values-ne/strings.xml
+++ b/packages/PrintSpooler/res/values-ne/strings.xml
@@ -49,7 +49,7 @@
<string name="print_options_collapsed" msgid="7455930445670414332">"कोल्याप्स गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
<string name="search" msgid="5421724265322228497">"खोज्नुहोस्"</string>
<string name="all_printers_label" msgid="3178848870161526399">"सबै प्रिन्टरहरू"</string>
- <string name="add_print_service_label" msgid="5356702546188981940">"सेवा थप्नुहोस्"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"सेवा हाल्नुहोस्"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"खोज बाकस देखाइयो"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"खोज बाकस लुकाइयो"</string>
<string name="print_add_printer" msgid="1088656468360653455">"प्रिन्टर थप्नुहोस्"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 750c156f95bd..c244ca0505ed 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -69,9 +69,6 @@ android_library {
"src/**/*.java",
"src/**/*.kt",
],
-
- min_sdk_version: "30",
-
}
// NOTE: Keep this module in sync with ./common.mk
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
index 83ef2911f8bd..d239f449fdde 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="settingslib_category_personal" msgid="1142302328104700620">"Osebno"</string>
- <string name="settingslib_category_work" msgid="4867750733682444676">"Služba"</string>
+ <string name="settingslib_category_work" msgid="4867750733682444676">"Delo"</string>
</resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
index 75ee30fbd367..9a44dcf7e269 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="settingslib_category_personal" msgid="1142302328104700620">"వ్యక్తిగతం"</string>
- <string name="settingslib_category_work" msgid="4867750733682444676">"ఆఫీస్"</string>
+ <string name="settingslib_category_work" msgid="4867750733682444676">"వర్క్"</string>
</resources>
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
index 5eaa4956b2e8..460bf9993b41 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.Hyphens
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
@@ -34,42 +35,48 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontWeight = FontWeight.Normal,
fontSize = 57.sp,
lineHeight = 64.sp,
- letterSpacing = (-0.2).sp
+ letterSpacing = (-0.2).sp,
+ hyphens = Hyphens.Auto,
),
displayMedium = TextStyle(
fontFamily = brand,
fontWeight = FontWeight.Normal,
fontSize = 45.sp,
lineHeight = 52.sp,
- letterSpacing = 0.0.sp
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
),
displaySmall = TextStyle(
fontFamily = brand,
fontWeight = FontWeight.Normal,
fontSize = 36.sp,
lineHeight = 44.sp,
- letterSpacing = 0.0.sp
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
),
headlineLarge = TextStyle(
fontFamily = brand,
fontWeight = FontWeight.Normal,
fontSize = 32.sp,
lineHeight = 40.sp,
- letterSpacing = 0.0.sp
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
),
headlineMedium = TextStyle(
fontFamily = brand,
fontWeight = FontWeight.Normal,
fontSize = 28.sp,
lineHeight = 36.sp,
- letterSpacing = 0.0.sp
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
),
headlineSmall = TextStyle(
fontFamily = brand,
fontWeight = FontWeight.Normal,
fontSize = 24.sp,
lineHeight = 32.sp,
- letterSpacing = 0.0.sp
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
),
titleLarge = TextStyle(
fontFamily = brand,
@@ -77,6 +84,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
),
titleMedium = TextStyle(
fontFamily = brand,
@@ -84,6 +92,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 20.sp,
lineHeight = 24.sp,
letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
),
titleSmall = TextStyle(
fontFamily = brand,
@@ -91,6 +100,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 18.sp,
lineHeight = 20.sp,
letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
),
bodyLarge = TextStyle(
fontFamily = plain,
@@ -98,6 +108,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
bodyMedium = TextStyle(
fontFamily = plain,
@@ -105,6 +116,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
bodySmall = TextStyle(
fontFamily = plain,
@@ -112,6 +124,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
labelLarge = TextStyle(
fontFamily = plain,
@@ -119,6 +132,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
labelMedium = TextStyle(
fontFamily = plain,
@@ -126,6 +140,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
labelSmall = TextStyle(
fontFamily = plain,
@@ -133,6 +148,7 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
),
)
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
index 5f2344ed97c0..01ba8f82850d 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Text.kt
@@ -19,6 +19,7 @@ package com.android.settingslib.spa.widget.ui
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -29,6 +30,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.theme.toMediumWeight
@@ -78,7 +80,7 @@ fun SettingsBody(
@Composable
fun PlaceholderTitle(title: String) {
Box(
- modifier = Modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize().padding(SettingsDimension.itemPadding),
contentAlignment = Alignment.Center,
) {
Text(
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
index 2b38b4cefe3e..8e0cf894bb28 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
@@ -34,11 +34,11 @@ import kotlinx.coroutines.runBlocking
/**
* The repository to load the App List data.
*/
-internal interface AppListRepository {
+interface AppListRepository {
/** Loads the list of [ApplicationInfo]. */
suspend fun loadApps(
userId: Int,
- showInstantApps: Boolean = false,
+ loadInstantApps: Boolean = false,
matchAnyUserForAdmin: Boolean = false,
): List<ApplicationInfo>
@@ -50,6 +50,9 @@ internal interface AppListRepository {
/** Gets the system app package names. */
fun getSystemPackageNamesBlocking(userId: Int): Set<String>
+
+ /** Loads the list of [ApplicationInfo], and filter base on `isSystemApp`. */
+ suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean): List<ApplicationInfo>
}
/**
@@ -62,13 +65,13 @@ object AppListRepositoryUtil {
AppListRepositoryImpl(context).getSystemPackageNamesBlocking(userId)
}
-internal class AppListRepositoryImpl(private val context: Context) : AppListRepository {
+class AppListRepositoryImpl(private val context: Context) : AppListRepository {
private val packageManager = context.packageManager
private val userManager = context.userManager
override suspend fun loadApps(
userId: Int,
- showInstantApps: Boolean,
+ loadInstantApps: Boolean,
matchAnyUserForAdmin: Boolean,
): List<ApplicationInfo> = coroutineScope {
val hiddenSystemModulesDeferred = async {
@@ -86,7 +89,7 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo
val hiddenSystemModules = hiddenSystemModulesDeferred.await()
val hideWhenDisabledPackages = hideWhenDisabledPackagesDeferred.await()
installedApplicationsAsUser.filter { app ->
- app.isInAppList(showInstantApps, hiddenSystemModules, hideWhenDisabledPackages)
+ app.isInAppList(loadInstantApps, hiddenSystemModules, hideWhenDisabledPackages)
}
}
@@ -136,17 +139,17 @@ internal class AppListRepositoryImpl(private val context: Context) : AppListRepo
): Flow<(app: ApplicationInfo) -> Boolean> =
userIdFlow.combine(showSystemFlow, ::showSystemPredicate)
- override fun getSystemPackageNamesBlocking(userId: Int) =
- runBlocking { getSystemPackageNames(userId) }
+ override fun getSystemPackageNamesBlocking(userId: Int) = runBlocking {
+ loadAndFilterApps(userId = userId, isSystemApp = true).map { it.packageName }.toSet()
+ }
- private suspend fun getSystemPackageNames(userId: Int): Set<String> =
- coroutineScope {
- val loadAppsDeferred = async { loadApps(userId) }
- val homeOrLauncherPackages = loadHomeOrLauncherPackages(userId)
- val showSystemPredicate =
- { app: ApplicationInfo -> isSystemApp(app, homeOrLauncherPackages) }
- loadAppsDeferred.await().filter(showSystemPredicate).map { it.packageName }.toSet()
+ override suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean) = coroutineScope {
+ val loadAppsDeferred = async { loadApps(userId) }
+ val homeOrLauncherPackages = loadHomeOrLauncherPackages(userId)
+ loadAppsDeferred.await().filter { app ->
+ isSystemApp(app, homeOrLauncherPackages) == isSystemApp
}
+ }
private suspend fun showSystemPredicate(
userId: Int,
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
index e3ea2e78756f..a0ff216875a2 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
@@ -76,7 +76,7 @@ class AppInfoProvider(private val packageInfo: PackageInfo) {
private fun AppVersion() {
if (packageInfo.versionName == null) return
Spacer(modifier = Modifier.height(4.dp))
- SettingsBody(packageInfo.versionName)
+ SettingsBody(packageInfo.versionNameBidiWrapped)
}
@Composable
@@ -84,10 +84,15 @@ class AppInfoProvider(private val packageInfo: PackageInfo) {
if (packageInfo.versionName == null) return
Divider()
Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
- val versionName = BidiFormatter.getInstance().unicodeWrap(packageInfo.versionName)
- SettingsBody(stringResource(R.string.version_text, versionName))
+ SettingsBody(stringResource(R.string.version_text, packageInfo.versionNameBidiWrapped))
}
}
+
+ private companion object {
+ /** Wrapped the version name, so its directionality still keep same when RTL. */
+ val PackageInfo.versionNameBidiWrapped: String
+ get() = BidiFormatter.getInstance().unicodeWrap(versionName)
+ }
}
@Composable
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
index 302f78081626..375ed60e17cf 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
@@ -108,7 +108,7 @@ class AppListRepositoryTest {
val appList = repository.loadApps(
userId = ADMIN_USER_ID,
- showInstantApps = false,
+ loadInstantApps = false,
)
assertThat(appList).containsExactly(NORMAL_APP)
@@ -120,7 +120,7 @@ class AppListRepositoryTest {
val appList = repository.loadApps(
userId = ADMIN_USER_ID,
- showInstantApps = true,
+ loadInstantApps = true,
)
assertThat(appList).containsExactly(NORMAL_APP, INSTANT_APP)
@@ -325,6 +325,21 @@ class AppListRepositoryTest {
assertThat(systemPackageNames).containsExactly(SYSTEM_APP.packageName)
}
+ @Test
+ fun loadAndFilterApps_loadNonSystemApp_returnExpectedValues() = runTest {
+ mockInstalledApplications(
+ apps = listOf(
+ NORMAL_APP, INSTANT_APP, SYSTEM_APP, UPDATED_SYSTEM_APP, HOME_APP, IN_LAUNCHER_APP
+ ),
+ userId = ADMIN_USER_ID,
+ )
+
+ val appList = repository.loadAndFilterApps(userId = ADMIN_USER_ID, isSystemApp = false)
+
+ assertThat(appList)
+ .containsExactly(NORMAL_APP, UPDATED_SYSTEM_APP, HOME_APP, IN_LAUNCHER_APP)
+ }
+
private suspend fun getShowSystemPredicate(showSystem: Boolean) =
repository.showSystemPredicate(
userIdFlow = flowOf(ADMIN_USER_ID),
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
index 6889e5d21ac0..9b224976e080 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListViewModelTest.kt
@@ -87,7 +87,7 @@ class AppListViewModelTest {
private object FakeAppListRepository : AppListRepository {
override suspend fun loadApps(
userId: Int,
- showInstantApps: Boolean,
+ loadInstantApps: Boolean,
matchAnyUserForAdmin: Boolean,
) = listOf(APP)
@@ -97,6 +97,9 @@ class AppListViewModelTest {
): Flow<(app: ApplicationInfo) -> Boolean> = flowOf { true }
override fun getSystemPackageNamesBlocking(userId: Int): Set<String> = emptySet()
+
+ override suspend fun loadAndFilterApps(userId: Int, isSystemApp: Boolean) =
+ emptyList<ApplicationInfo>()
}
private object FakeAppRepository : AppRepository {
diff --git a/packages/SettingsLib/TEST_MAPPING b/packages/SettingsLib/TEST_MAPPING
new file mode 100644
index 000000000000..f6ada4c1ab7f
--- /dev/null
+++ b/packages/SettingsLib/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+ "presubmit": [
+ {
+ "name": "SettingsLibUnitTests"
+ },
+ {
+ "name": "SpaPrivilegedLibTests"
+ },
+ {
+ "name": "SettingsSpaUnitTests"
+ }
+ ]
+}
diff --git a/packages/SettingsLib/Utils/res/values-as/strings.xml b/packages/SettingsLib/Utils/res/values-as/strings.xml
new file mode 100644
index 000000000000..4463586e4741
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-as/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"কৰ্মস্থান <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-bn/strings.xml b/packages/SettingsLib/Utils/res/values-bn/strings.xml
new file mode 100644
index 000000000000..f7c9a07d42fb
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-bn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"অফিসের <xliff:g id="APP_NAME">%s</xliff:g> অ্যাপ"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-et/strings.xml b/packages/SettingsLib/Utils/res/values-et/strings.xml
new file mode 100644
index 000000000000..0953870b0023
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-et/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Töö: <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-eu/strings.xml b/packages/SettingsLib/Utils/res/values-eu/strings.xml
new file mode 100644
index 000000000000..47439130ad37
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-eu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Laneko <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml b/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000000..57405f4c08bb
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> dans le profil professionnel"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-gl/strings.xml b/packages/SettingsLib/Utils/res/values-gl/strings.xml
new file mode 100644
index 000000000000..32d764e1d09c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-gl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Aplicación <xliff:g id="APP_NAME">%s</xliff:g> do traballo"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-gu/strings.xml b/packages/SettingsLib/Utils/res/values-gu/strings.xml
new file mode 100644
index 000000000000..4f253841602e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-gu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ઑફિસ માટે <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-it/strings.xml b/packages/SettingsLib/Utils/res/values-it/strings.xml
new file mode 100644
index 000000000000..e7f25999142e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-it/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"App <xliff:g id="APP_NAME">%s</xliff:g> di lavoro"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ka/strings.xml b/packages/SettingsLib/Utils/res/values-ka/strings.xml
new file mode 100644
index 000000000000..8cf1762e9bfb
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ka/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"სამსახურის <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-kk/strings.xml b/packages/SettingsLib/Utils/res/values-kk/strings.xml
new file mode 100644
index 000000000000..1ac00048cfb6
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-kk/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Жұмысқа арналған <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-kn/strings.xml b/packages/SettingsLib/Utils/res/values-kn/strings.xml
new file mode 100644
index 000000000000..97bd0069f765
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-kn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ಕೆಲಸ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-lv/strings.xml b/packages/SettingsLib/Utils/res/values-lv/strings.xml
new file mode 100644
index 000000000000..3026f06ac105
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-lv/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Darba lietotne <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ml/strings.xml b/packages/SettingsLib/Utils/res/values-ml/strings.xml
new file mode 100644
index 000000000000..59e52483c4e5
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ml/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ഔദ്യോഗിക <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-mn/strings.xml b/packages/SettingsLib/Utils/res/values-mn/strings.xml
new file mode 100644
index 000000000000..4fae367adaca
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-mn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Ажлын <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-mr/strings.xml b/packages/SettingsLib/Utils/res/values-mr/strings.xml
new file mode 100644
index 000000000000..6b770eab9be0
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-mr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-my/strings.xml b/packages/SettingsLib/Utils/res/values-my/strings.xml
new file mode 100644
index 000000000000..9533ae0c4f51
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-my/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"အလုပ်သုံး <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-nb/strings.xml b/packages/SettingsLib/Utils/res/values-nb/strings.xml
new file mode 100644
index 000000000000..a513b456d87a
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-nb/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> for jobb"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ne/strings.xml b/packages/SettingsLib/Utils/res/values-ne/strings.xml
new file mode 100644
index 000000000000..54a8d693c349
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ne/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"कार्यालयको प्रोफाइल <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-or/strings.xml b/packages/SettingsLib/Utils/res/values-or/strings.xml
new file mode 100644
index 000000000000..f0d3b1866d3c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-or/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ୱାର୍କ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pa/strings.xml b/packages/SettingsLib/Utils/res/values-pa/strings.xml
new file mode 100644
index 000000000000..79151b2d9445
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pa/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ਕੰਮ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pl/strings.xml b/packages/SettingsLib/Utils/res/values-pl/strings.xml
new file mode 100644
index 000000000000..190f6d1629aa
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (aplikacja służbowa)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sl/strings.xml b/packages/SettingsLib/Utils/res/values-sl/strings.xml
new file mode 100644
index 000000000000..ee567e1d1822
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Delovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ta/strings.xml b/packages/SettingsLib/Utils/res/values-ta/strings.xml
new file mode 100644
index 000000000000..b519e621ec2f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ta/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"பணி <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ur/strings.xml b/packages/SettingsLib/Utils/res/values-ur/strings.xml
new file mode 100644
index 000000000000..301e92c86a5b
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ur/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ورک <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/res/drawable/ic_docked_tablet.xml b/packages/SettingsLib/res/drawable/ic_docked_tablet.xml
new file mode 100644
index 000000000000..96a4900f361f
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_docked_tablet.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M480,280Q497,280 508.5,268.5Q520,257 520,240Q520,223 508.5,211.5Q497,200 480,200Q463,200 451.5,211.5Q440,223 440,240Q440,257 451.5,268.5Q463,280 480,280ZM120,720Q87,720 63.5,696.5Q40,673 40,640L60,160Q60,127 83.5,103.5Q107,80 140,80L820,80Q853,80 876.5,103.5Q900,127 900,160L920,640Q920,673 896.5,696.5Q873,720 840,720L120,720ZM120,640L840,640Q840,640 840,640Q840,640 840,640L820,160Q820,160 820,160Q820,160 820,160L140,160Q140,160 140,160Q140,160 140,160L120,640Q120,640 120,640Q120,640 120,640ZM320,880Q259,880 209.5,850Q160,820 160,765L160,720L240,720L240,760Q253,780 274.5,790Q296,800 320,800L640,800Q664,800 685.5,790.5Q707,781 720,761L720,720L800,720L800,765Q800,820 750.5,850Q701,880 640,880L320,880ZM480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 0e6f207b2060..119bb73bb96e 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Sopas"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Hierdie foon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Hierdie tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</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>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index a45359469280..89d68c32faee 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ልክ አሁን"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ይህ ስልክ"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ይህ ጡባዊ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ይህ ስልክ"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"በዚህ መሣሪያ ላይ ማጫወት አልተቻለም"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ለመቀየር መለያ ያልቁ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9e3b26539e5b..f7e2b2d0e71a 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صوت عالي الدقة"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سماعات الأذن الطبية"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"تمّ التوصيل بسماعات الأذن الطبية"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"‏متصل بـ LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"متصل بالإعدادات الصوتية للوسائط"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"اختيار ملف شخصي"</string>
<string name="category_personal" msgid="6236798763159385225">"التطبيقات الشخصية"</string>
<string name="category_work" msgid="4014193632325996115">"تطبيقات العمل"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"استنساخ"</string>
<string name="development_settings_title" msgid="140296922921597393">"خيارات المطورين"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"تفعيل خيارات المطورين"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"تعيين خيارات تطوير التطبيق"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"للتو"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"هذا الهاتف"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"هذا الجهاز اللوحي"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"هذا الهاتف"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"يمكنك إعادة المحاولة بعد الإعلان."</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"يجب تنشيط الجهاز لتشغيل الوسائط هنا."</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"غير مسموح لهذا الجهاز بتشغيل الوسائط."</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"لا يمكن تشغيل هذه الوسائط هنا."</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>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"أعِد المحاولة بعد الإعلان"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"نشِّط الجهاز للتشغيل هنا"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"غير مسموح له بتشغيل وسائط"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"هذه الوسائط غير متوافقة"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
<string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 00c9a3ceaa66..594ed7ba6311 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"এইচ্ছডি অডিঅ’"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"শ্ৰৱণ যন্ত্ৰ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিঅ’"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"শ্ৰৱণ যন্ত্ৰলৈ সংযোগ কৰা হৈছে"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE অডিঅ’ৰ সৈতে সংযোগ কৰক"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"মিডিয়া অডিঅ’লৈ সংযোগ হৈছে"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"প্ৰ’ফাইল বাছনি কৰক"</string>
<string name="category_personal" msgid="6236798763159385225">"ব্যক্তিগত"</string>
<string name="category_work" msgid="4014193632325996115">"কৰ্মস্থান-সম্পৰ্কীয়"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ক্ল’ন"</string>
<string name="development_settings_title" msgid="140296922921597393">"বিকাশকৰ্তাৰ বিকল্পসমূহ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"বিকাশকৰ্তা বিষয়ক বিকল্পসমূহ সক্ষম কৰক"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"এপৰ বিকাশৰ বাবে বিকল্পসমূহ ছেট কৰক"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"এই মাত্ৰ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"এই ফ’নটো"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"এই টেবলেটটো"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফ’নটো"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইচটো প্লে\' কৰিব নোৱাৰি"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"সলনি কৰিবলৈ একাউণ্ট আপগ্ৰে’ড কৰক"</string>
@@ -581,7 +585,7 @@
<string name="user_add_user_message_short" msgid="3295959985795716166">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ ঠাই ছেট আপ কৰাৰ প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে অন্য সকলো ব্যৱহাৰকাৰীৰ বাবে এপ্ আপডে\'ট কৰিব পাৰে।"</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"এই ব্যৱহাৰকাৰীগৰাকীক এগৰাকী প্ৰশাসক বনাবনে?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"প্ৰশাসকৰ ওচৰত কিছুমান বিশেষাধিকাৰ আছে, যিবোৰ অন্য ব্যৱহাৰকাৰীৰ নাই। এগৰাকী প্ৰশাসকে সকলো ব্যৱহাৰকাৰীক পৰিচালনা কৰিব, এই ডিভাইচটো আপডে’ট অথবা ৰিছেট কৰিব, ছেটিং সংশোধন কৰিব, ইনষ্টল কৰি থোৱা আটাইবোৰ এপ্ চাব আৰু অন্য লোকৰ বাবে প্ৰশাসকৰ বিশেষাধিকাৰ প্ৰদান কৰিব অথবা প্ৰত্যাহাৰ কৰিব পাৰে।"</string>
- <string name="user_grant_admin_button" msgid="5441486731331725756">"প্ৰশাসকৰ বনাওক"</string>
+ <string name="user_grant_admin_button" msgid="5441486731331725756">"প্ৰশাসক বনাওক"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"ব্যৱহাৰকাৰী এতিয়া ছেট আপ কৰিবনে?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"ডিভাইচটো লৈ নিজৰ ঠাই ছেটআপ কৰিবলৈ নতুন ব্যৱহাৰকাৰী উপলব্ধ থকাটো নিশ্চিত কৰক"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"এতিয়া প্ৰ\'ফাইল ছেট আপ কৰিবনে?"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index a9856302e519..0b4779fb9893 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eşitmə cihazları"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eşitmə Aparatlarına qoşuldu"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE audiosuna qoşulub"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Media audioya birləşdirilib"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profil seçin"</string>
<string name="category_personal" msgid="6236798763159385225">"Şəxsi"</string>
<string name="category_work" msgid="4014193632325996115">"İş"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klonlayın"</string>
<string name="development_settings_title" msgid="140296922921597393">"Developer seçimləri"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Developer variantlarını aktiv edin"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Tətbiq inkişafı seçimlərini təyin et"</string>
@@ -457,7 +455,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"İstifadəyə əsasən təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> olana qədər davam edəcək"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> olana qədər"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g> radəsinə qədər"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batareya <xliff:g id="TIME">%1$s</xliff:g> radələrinə qədər boşala bilər"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Maksimum <xliff:g id="THRESHOLD">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"İndicə"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Bu planşet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oxutmaq mümkün deyil"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"Keçirmək üçün hesabı təkmilləşdirin"</string>
- <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Burada endirmələri oxutmaq mümkün deyil"</string>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamdan sonra yenidən cəhd edin"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Burada oxutmaq üçün cihazı oyadın"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Cihaz oxudulmaq üçün təsdiqlənməyib"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Bu medianı burada oxutmaq mümkün deyil"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oxutmaq olmur"</string>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"Keçirmək üçün hesabı güncəllə"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Burada endirmələri oxutmaq olmur"</string>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamdan sonra yenidən sına"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Burada oxutmaqçün cihazı oyat"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Cihaz oxutmaq üçün təsdiqlənməyib"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Bu medianı burada oxutmaq olmur"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio cihaz"</string>
<string name="help_label" msgid="3528360748637781274">"Yardım və rəy"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 50249e05fe83..298835fa6724 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -60,7 +60,7 @@
<string name="wifi_not_in_range" msgid="1541760821805777772">"Nije u opsegu"</string>
<string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
- <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="saved_network" msgid="7143698034077223645">"Čuva <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
<string name="connected_via_app" msgid="3532267661404276584">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Otkaži"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Uparivanje omogućava pristup kontaktima i istoriji poziva nakon povezivanja."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nije moguće komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio/la uparivanje"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Računar"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne možete da pustite na ovom uređaju"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite nalog radi prebacivanja"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 10587feebb05..666dbb15d2c8 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Аўдыя ў HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Аўдыя ў HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слыхавыя апараты"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Падключана да слыхавых апаратаў"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Падключана да LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Падключана да аўдыё медыа"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Выбраць профіль"</string>
<string name="category_personal" msgid="6236798763159385225">"Асабісты"</string>
<string name="category_work" msgid="4014193632325996115">"Працоўны"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Параметры распрацоўшчыка"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Уключыць параметры распрацоўшчыка"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Налада параметраў для распрацоўкі прыкладанняў"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Толькі што"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Гэты тэлефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Гэты планшэт"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Гэты тэлефон"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не ўдаецца прайграць на гэтай прыладзе"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Для пераключэння перайдзіце на іншую версію ўліковага запісу"</string>
@@ -577,8 +581,8 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Карыстальнік"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Абмежаваны профiль"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Дадаць новага карыстальніка?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Вы можаце адкрыць доступ да гэтай прылады іншым людзям шляхам стварэння дадатковых карыстальнікаў. Кожны карыстальнік мае свой уласны раздзел, на якім ён можа наладзіць свае праграмы, шпалеры і іншае. Карыстальнікі таксама могуць наладжваць параметры прылады, напрыклад Wi-Fi, якія ўплываюць на ўсіх.\n\nКалі вы дадаяце новага карыстальніка, ён павінен наладзіць свой раздзел.\n\nЛюбы карыстальнік можа абнаўляць праграмы для ўсіх астатніх карыстальнікаў. Спецыяльныя магчымасці наладжваюцца асабіста кожным карыстальнікам."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Пасля стварэння профіля яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Вы можаце адкрыць доступ да гэтай прылады іншым карыстальнікам шляхам стварэння дадатковых профіляў. Кожны карыстальнік будзе мець свой уласны профіль, на якім ён зможа наладзіць свае праграмы, шпалеры і іншае. Карыстальнікі таксама змогуць наладжваць параметры прылады, напрыклад Wi-Fi, якія ўплываюць на ўсіх.\n\nКалі вы дадаяце новага карыстальніка, ён павінен наладзіць свой профіль.\n\nЛюбы карыстальнік можа абнаўляць праграмы для ўсіх астатніх карыстальнікаў. Спецыяльныя магчымасці наладжваюцца асабіста кожным карыстальнікам."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Пасля стварэння профілю яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Зрабіць гэтага карыстальніка адміністратарам?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Адміністратары маюць спецыяльныя правы, якіх няма ў звычайных карыстальнікаў. Адмінстратар можа кіраваць усімі карыстальнікамі, абнаўляць або скідваць ПЗ прылады, змяняць налады, праглядаць усталяваныя праграмы, даваць іншым карыстальнікам або адклікаць правы адміністратара."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Зрабіць адміністратарам"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 239be746d728..94466348282f 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Висококачествено аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слухови апарати"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Установена е връзка със слухов апарат"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Свързано с LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Установена е връзка с медийно аудио"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Отказ"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"При свързване сдвояването предоставя достъп до вашите контакти и история на обажданията."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради неправилен ПИН или код за достъп."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправилен ПИН или ключ за достъп."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не може да се свърже с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Сдвояването е отхвърлено от <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компютър"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Избор на потребителски профил"</string>
<string name="category_personal" msgid="6236798763159385225">"Лични"</string>
<string name="category_work" msgid="4014193632325996115">"Служебни"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клониране"</string>
<string name="development_settings_title" msgid="140296922921597393">"Опции за програмисти"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Активиране на опциите за програмисти"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Задаване на опции за програмиране на приложения"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Току-що"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Този телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Този таблет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Този телефон"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Възпроизвеждането не е възможно на това устройство"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надстройте профила, за да превключите"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 57333a03a217..0eb5b756a033 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"ডিসকানেক্ট হচ্ছে..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"কানেক্ট হচ্ছে..."</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"কানেক্ট করা আছে<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"যুক্ত করা হচ্ছে..."</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"পেয়ার করা হচ্ছে..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"কানেক্ট করা আছে (ফোনের অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"কানেক্ট করা আছে (মিডিয়ার অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"কানেক্ট করা আছে (ফোনের বা মিডিয়ার অডিও ছাড়া)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD অডিও: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD অডিও"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"হিয়ারিং এড"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিও"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"হিয়ারিং এডের সাথে কানেক্ট করা হয়েছে"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE অডিও কানেক্ট করা হয়েছে"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"মিডিয়া অডিওতে কানেক্ট রয়েছে"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"প্রোফাইল বেছে নিন"</string>
<string name="category_personal" msgid="6236798763159385225">"ব্যক্তিগত"</string>
<string name="category_work" msgid="4014193632325996115">"অফিস"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ক্লোন"</string>
<string name="development_settings_title" msgid="140296922921597393">"ডেভেলপার বিকল্প"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ডেভেলপার বিকল্প সক্ষম করুন"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"অ্যাপ্লিকেশান উন্নয়নের জন্য বিকল্পগুলি সেট করুন"</string>
@@ -547,10 +545,16 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"এখনই"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"এই ফোন"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"এই ট্যাবলেট"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফোনটি"</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>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"পাল্টাতে অ্যাকাউন্ট আপগ্রেড করুন"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"এতে ডাউনলোড করা কন্টেন্ট প্লে করা যাবে না"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"বিজ্ঞাপনের পরে আবার চেষ্টা করুন"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"এখানে চালানোর জন্য ডিভাইসকে জাগান"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"চালানোর জন্য ডিভাইসের অনুমতি নেই"</string>
@@ -576,7 +580,7 @@
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"আপনি আপনার অ্যাকাউন্ট থেকে অ্যাপ্লিকেশন এবং কন্টেন্ট অ্যাক্সেস সীমাবদ্ধ করতে পারেন"</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"ব্যবহারকারী"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"সীমাবদ্ধ প্রোফাইল"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যবহারকারী জুড়বেন?"</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যবহারকারী যোগ করবেন?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"আপনি একাধিক ব্যবহারকারীর আইডি তৈরি করে অন্যদের সাথে এই ডিভাইসটি শেয়ার করতে পারেন। ডিভাইসের স্টোরেজে প্রত্যেক ব্যবহারকারী তার নিজস্ব জায়গা পাবেন যা তিনি অ্যাপ, ওয়ালপেপার এবং আরও অনেক কিছু দিয়ে কাস্টমাইজ করতে পারেন। ওয়াই-ফাই এর মতো ডিভাইস সেটিংস, যেগুলি সকলের ক্ষেত্রে প্রযোজ্য হয়, সেগুলি ব্যবহারকারীরা পরিবর্তন করতে পারবেন।\n\nনতুন ব্যবহারকারীর আইডি যোগ করলে সেই ব্যক্তিকে স্টোরেজে তার নিজের জায়গা সেট-আপ করতে হবে।\n\nঅন্যান্য ব্যবহারকারীদের হয়ে যে কোনও ব্যবহারকারী অ্যাপ আপডেট করতে পারবেন। তবে ব্যবহারযোগ্যতার সেটিংস এবং পরিষেবা নতুন ব্যবহারকারীর ক্ষেত্রে প্রযোজ্য নাও হতে পারে।"</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"এই ব্যবহারকারীকে অ্যাডমিন করবেন?"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index fd0868667be0..345cad1792d3 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nije moguće reproducirati na uređaju"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun da promijenite"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 52bc7b7a1bc0..899bc7d49cfd 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Àudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Àudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiòfons"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"S\'ha connectat als audiòfons"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connectat a LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connectat a l\'àudio del mitjà"</string>
@@ -183,7 +182,7 @@
<string name="tts_default_lang_title" msgid="4698933575028098940">"Idioma"</string>
<string name="tts_lang_use_system" msgid="6312945299804012406">"Utilitza l\'idioma del sistema"</string>
<string name="tts_lang_not_selected" msgid="7927823081096056147">"No has seleccionat cap idioma"</string>
- <string name="tts_default_lang_summary" msgid="9042620014800063470">"Defineix la llengua utilitzada per a la síntesi de veu"</string>
+ <string name="tts_default_lang_summary" msgid="9042620014800063470">"Defineix la llengua utilitzada per al text enunciat"</string>
<string name="tts_play_example_title" msgid="1599468547216481684">"Vull escoltar un exemple"</string>
<string name="tts_play_example_summary" msgid="634044730710636383">"Reprodueix una breu demostració de síntesi de veu"</string>
<string name="tts_install_data_title" msgid="1829942496472751703">"Instal·la dades de veu"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Tria un perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Treball"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clona"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opcions per a desenvolupadors"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activa les opcions per a desenvolupadors"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Defineix les opcions per al desenvolupament d\'aplicacions"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Aquest telèfon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Aquesta tauleta"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Aquest telèfon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"No es pot reproduir en aquest dispositiu"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualitza el compte per canviar"</string>
@@ -613,8 +617,8 @@
<string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Aquesta acció iniciarà una nova sessió de convidat i suprimirà totes les aplicacions i dades de la sessió actual"</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sortir del mode de convidat?"</string>
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Aquesta acció suprimirà les aplicacions i dades de la sessió de convidat actual"</string>
- <string name="grant_admin" msgid="4323199171790522574">"Sí, converteix en administrador"</string>
- <string name="not_grant_admin" msgid="3557849576157702485">"No, no converteixis en administrador"</string>
+ <string name="grant_admin" msgid="4323199171790522574">"Sí, converteix-lo en administrador"</string>
+ <string name="not_grant_admin" msgid="3557849576157702485">"No, no el converteixis en administrador"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Surt"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Desar l\'activitat de convidat?"</string>
<string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pots desar l\'activitat de la sessió actual o suprimir totes les apps i dades"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8da3a51d26ed..1c8fe92fb3e2 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -545,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Právě teď"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tento telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tento tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Na tomto zařízení média přehrávat nelze"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"Pokud chcete přejít, upgradujte účet"</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>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Stažený obsah zde nelze přehrát"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Zkuste to znovu po reklamě"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Pokud zde chcete přehrávat média, probuďte zařízení"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Zařízení není schváleno k přehrávání"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Zařízení je třeba probudit"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Není schváleno k přehrávání"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Tato média zde přehrát nelze"</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>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kabelové audiozařízení"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 0f1459dd713a..92531487b2b8 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -115,10 +115,9 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-lyd"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Forbundet til høreapparater"</string>
- <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Forbundet med LE Audio"</string>
+ <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Forbundet med LE-lyd"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Forbundet til medielyd"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Forbundet til telefonlyd"</string>
<string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Forbundet til filoverførselsserver"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Vælg profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personlig"</string>
<string name="category_work" msgid="4014193632325996115">"Arbejde"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Indstillinger for udviklere"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Aktivér indstillinger for udviklere"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Konfigurer valgmuligheder for appudvikling"</string>
@@ -547,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Lige nu"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Denne telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Denne tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefon"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Indholdet kan ikke afspilles på denne enhed"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke afspilles på denne enhed"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Opgrader kontoen for at skifte"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads kan ikke afspilles her"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prøv igen efter annoncen"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Væk enheden for at afspille her"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheden er ikke godkendt til afspilning"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheden er ikke godkendt"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Mediet kan ikke afspilles her"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 57376ab7adfc..4c6f0c1c4b82 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -114,7 +114,7 @@
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Zugriff auf SIM"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-Audio"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörhilfen"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörgeräte"</string>
<string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Mit Hörhilfen verbunden"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Mit LE Audio verbunden"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Gerade eben"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Dieses Smartphone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Dieses Tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Dieses Smartphone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Wiedergabe auf diesem Gerät nicht möglich"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Zum Umstellen Kontoupgrade durchführen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 3b534a693a43..64e9bcf9389f 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Μόλις τώρα"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Αυτό το τηλέφωνο"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Αυτό το tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφ."</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Δεν είναι δυνατή η αναπαραγωγή σε αυτήν τη συσκευή"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Αναβαθμίστε τον λογαριασμό για εναλλαγή"</string>
@@ -575,13 +581,13 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Χρήστης"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Προφίλ περιορ. πρόσβασης"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Προσθήκη νέου χρήστη;"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Μπορείτε να μοιραστείτε αυτήν τη συσκευή με άλλα άτομα, δημιουργώντας επιπλέον χρήστες. Κάθε χρήστης θα έχει το δικό του χώρο, τον οποίο μπορεί να προσαρμόσει με τις δικές του εφαρμογές, ταπετσαρία κ.λπ. Οι χρήστες μπορούν επίσης να προσαρμόσουν ρυθμίσεις της συσκευής, όπως το Wi‑Fi, που επηρεάζουν τους πάντες.\n\nΚατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες. Οι ρυθμίσεις και οι υπηρεσίες προσβασιμότητας ενδέχεται να μην μεταφερθούν στον νέο χρήστη."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει το χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Μπορείτε να μοιραστείτε αυτήν τη συσκευή με άλλα άτομα, δημιουργώντας επιπλέον χρήστες. Κάθε χρήστης θα έχει τον δικό του χώρο, τον οποίο μπορεί να προσαρμόσει με τις δικές του εφαρμογές, ταπετσαρία κ.λπ. Οι χρήστες μπορούν επίσης να προσαρμόσουν ρυθμίσεις της συσκευής, όπως το Wi‑Fi, που επηρεάζουν τους πάντες.\n\nΚατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες. Οι ρυθμίσεις και οι υπηρεσίες προσβασιμότητας ενδέχεται να μην μεταφερθούν στον νέο χρήστη."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Να εκχωρηθούν δικαιώματα διαχειριστή σε αυτόν τον χρήστη;"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Οι διαχειριστές έχουν ειδικά προνόμια που δεν έχουν οι υπόλοιποι χρήστες Ένας διαχειριστής μπορεί να διαχειριστεί όλους τους χρήστες, να ενημερώσει ή να επαναφέρει αυτήν τη συσκευή, να τροποποιήσει τις ρυθμίσεις, να δει όλες τις εγκατεστημένες εφαρμογές και να εκχωρήσει ή να ανακαλέσει προνόμια διαχειριστή άλλων χρηστών."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Εκχώρηση δικαιωμάτων διαχειριστή"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Να γίνει ρύθμιση χρήστη τώρα;"</string>
- <string name="user_setup_dialog_message" msgid="269931619868102841">"Βεβαιωθείτε ότι ο χρήστης μπορεί να πάρει τη συσκευή και ρυθμίστε το χώρο του"</string>
+ <string name="user_setup_dialog_message" msgid="269931619868102841">"Βεβαιωθείτε ότι ο χρήστης μπορεί να πάρει τη συσκευή και ρυθμίστε τον χώρο του"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Να γίνει ρύθμιση προφίλ τώρα;"</string>
<string name="user_setup_button_setup_now" msgid="1708269547187760639">"Ρύθμιση τώρα"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"Όχι τώρα"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 07187945cfc7..6779e89e572d 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Work"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 4066992d53f6..9ee30e11a404 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -545,6 +545,9 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
+ <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dock speaker"</string>
+ <string name="media_transfer_external_device_name" msgid="2588672258721846418">"External Device"</string>
+ <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Cant play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 07187945cfc7..6779e89e572d 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Work"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 07187945cfc7..6779e89e572d 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Work"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index bd6ffa045fbc..9ad8a393f469 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -545,6 +545,9 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎Just now‎‏‎‎‏‎"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎This phone‎‏‎‎‏‎"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎This tablet‎‏‎‎‏‎"</string>
+ <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎Dock speaker‎‏‎‎‏‎"</string>
+ <string name="media_transfer_external_device_name" msgid="2588672258721846418">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎External Device‎‏‎‎‏‎"</string>
+ <string name="media_transfer_default_device_name" msgid="4315604017399871828">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎Connected device‎‏‎‎‏‎"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎This phone‎‏‎‎‏‎"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎Cant play on this device‎‏‎‎‏‎"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎Upgrade account to switch‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 351a319f1ba4..8946365051d7 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -99,9 +99,9 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"I: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activado"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo; solo izquierda"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo; solo derecha"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo; izquierda y derecha"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo; solo oído izquierdo"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo; solo oído derecho"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo; oídos izquierdo y derecho"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimedia"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Llamadas telefónicas"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"La sincronización te permite acceder a los contactos y al historial de llamadas cuando el dispositivo está conectado."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque la llave de acceso o el PIN son incorrectos."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: llave de acceso o PIN incorrectos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"No se puede establecer la comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vínculo rechazado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computadora"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Recién"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Esta tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index f43b67d5c1ae..82686825d521 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audífonos"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audífonos"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectado a LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado al audio del medio"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Seleccionar perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clonar"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Habilitar opciones para desarrolladores"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones de desarrollo de aplicaciones"</string>
@@ -331,7 +329,7 @@
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar aplicaciones por USB"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comprueba las aplicaciones instaladas por ADB/ADT para detectar comportamientos dañinos"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Muestra los dispositivos Bluetooth sin nombre (solo direcciones MAC)"</string>
- <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (p. ej., volumen excesivamente alto o falta de control)"</string>
+ <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de \\nvolumen con dispositivos remotos (p. ej., volumen excesivamente alto o falta de control)"</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Habilita la pila de funciones de Bluetooth Gabeldorsche"</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Habilita la función de conectividad mejorada."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
@@ -547,8 +545,14 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Esta tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir contenido en este dispositivo"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir descargas aquí"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prueba de nuevo después del anuncio"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index a0ad05ebe7be..8e30e3dce29c 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-heli"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuuldeaparaadid"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Kuuldeaparaatidega ühendatud"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ühendatud üksusega LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ühendatud meediumiheliga"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profiili valimine"</string>
<string name="category_personal" msgid="6236798763159385225">"Isiklik"</string>
<string name="category_work" msgid="4014193632325996115">"Töö"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Kloonimine"</string>
<string name="development_settings_title" msgid="140296922921597393">"Arendaja valikud"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Arendaja valikute lubamine"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Rakenduse arenduse valikute määramine"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Äsja"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"See telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"See tahvelarvuti"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"See telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Selles seadmes ei saa esitada"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Lülitamiseks täiendage kontot"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 19da6fcaa83c..7d64cfaaf66b 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Kalitate handiko audioa"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audifonoak"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Kontsumo txikiko Bluetooth bidezko audioa"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Audifonoetara konektatuta"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE audio-ra konektatuta"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Euskarriaren audiora konektatuta"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Aukeratu profila"</string>
<string name="category_personal" msgid="6236798763159385225">"Pertsonalak"</string>
<string name="category_work" msgid="4014193632325996115">"Lanekoak"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klonatu"</string>
<string name="development_settings_title" msgid="140296922921597393">"Garatzaileentzako aukerak"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Gaitu garatzaileen aukerak"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ezarri aplikazioak garatzeko aukerak"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Oraintxe"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Telefono hau"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tableta hau"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefono hau"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ezin da erreproduzitu gailu honetan"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Aldatzeko, bertsio-berritu kontua"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9f3359225cb9..3ba5436e98a9 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"هم‌اکنون"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"این تلفن"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"این رایانه لوحی"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"این تلفن"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"نمی‌توان در این دستگاه پخش کرد"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"برای تغییر، حساب را ارتقا دهید"</string>
@@ -575,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"کاربر"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"نمایه محدود شده"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"کاربر جدیدی اضافه می‌کنید؟"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"‏با ایجاد کاربران بیشتر، می‌توانید این دستگاه را با دیگران به‌اشتراک بگذارید. هر کاربر فضای مخصوص به خودش را دارد که می‌تواند آن را با برنامه‌ها، کاغذدیواری و موارد دیگر سفارشی کند. همچنین کاربران می‌توانند تنظیماتی در دستگاه ایجاد کنند، مانند تنظیمات Wi-Fi، که بر تنظیمات بقیه اثر دارد.\n\nوقتی کاربر جدیدی اضافه می‌کنید، آن شخص باید فضای خودش را تنظیم کند.\n\nهر کاربر می‌تواند برنامه‌ها را برای سایر کاربران به‌روزرسانی کند. دسترس‌پذیری، تنظیمات، و سرویس‌ها قابل‌انتقال به کاربر جدید نیستند."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"‏با ایجاد کاربران بیشتر، می‌توانید از این دستگاه مشترکاً استفاده کنید. هر کاربر فضای مخصوص به خودش را دارد که می‌تواند آن را با برنامه‌ها، کاغذدیواری و موارد دیگر سفارشی کند. علاوه‌براین کاربران می‌توانند تنظیماتی در دستگاه ایجاد کنند، مانند تنظیمات Wi-Fi، که بر تنظیمات بقیه اثر دارد.\n\nوقتی کاربر جدیدی اضافه می‌کنید، آن شخص باید فضای خودش را تنظیم کند.\n\nهر کاربر می‌تواند برنامه‌ها را برای سایر کاربران به‌روزرسانی کند. دسترس‌پذیری، تنظیمات، و سرویس‌ها قابل‌انتقال به کاربر جدید نیستند."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"وقتی کاربر جدیدی اضافه می‌کنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری می‌تواند برنامه‌ها را برای همه کاربران دیگر به‌روزرسانی کند."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"این کاربر سرپرست شود؟"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"سرپرستان امتیازهای ویژه‌ای دارند که کاربران دیگر ندارند. سرپرست می‌تواند همه کاربران را مدیریت کند، این دستگاه را به‌روز یا بازنشانی کند، تنظیمات را تغییر دهد، همه برنامه‌های نصب‌شده را ببیند، و امتیازهای سرپرست را به دیگران اعطا کند یا از آن‌ها بگیرد."</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 1909ec620b33..d1bf50a106a2 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ääni: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ääni"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuulolaitteet"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Yhdistetty kuulolaitteisiin"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio yhdistetty"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Yhdistetty median ääneen"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Peru"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Laiteparin muodostaminen mahdollistaa yhteystietojen ja soittohistorian käyttämisen yhteyden aikana."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Laiteparin muodostaminen laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g> epäonnistui."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Laiteparia (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ei voitu muodostaa, koska PIN-koodi tai avain oli virheellinen."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Laiteparia (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ei voitu muodostaa, koska PIN tai avain oli väärä."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Ei yhteyttä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Laite <xliff:g id="DEVICE_NAME">%1$s</xliff:g> torjui laitepariyhteyden."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Tietokone"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Valitse profiili"</string>
<string name="category_personal" msgid="6236798763159385225">"Henkilökohtainen"</string>
<string name="category_work" msgid="4014193632325996115">"Työ"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klooni"</string>
<string name="development_settings_title" msgid="140296922921597393">"Kehittäjäasetukset"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Ota kehittäjäasetukset käyttöön"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Valitse sovellusten kehittämisasetukset"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Äsken"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tämä puhelin"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tämä tabletti"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tämä puhelin"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ei voi toistaa tällä laitteella"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Vaihda päivittämällä tili"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 94dbeef13280..11579af82206 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Déconnexion…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connexion en cours…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Connecté à <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Association…"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Association en cours…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Connecté (aucun téléphone) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Connecté (aucun média) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Connecté (aucun téléphone ni média) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -99,7 +99,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"G : charge à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>; D : charge à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, gauche seulement"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche seulement"</string>
<string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, droite seulement"</string>
<string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, gauche et droite"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Paramètres audio du support"</string>
@@ -520,7 +520,7 @@
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Moins longtemps."</string>
<string name="cancel" msgid="5665114069455378395">"Annuler"</string>
- <string name="next" msgid="2699398661093607009">"Suivante"</string>
+ <string name="next" msgid="2699398661093607009">"Suivant"</string>
<string name="back" msgid="5554327870352703710">"Retour"</string>
<string name="save" msgid="3745809743277153149">"Enregistrer"</string>
<string name="okay" msgid="949938843324579502">"OK"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Cette tablette"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de faire jouer le contenu sur cet appareil"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à jour le compte pour passer à la version payante"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 22d359874073..cf444a6d67b5 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Appareils auditifs"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connexion établie avec les appareils auditifs"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connecté à LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connecté aux paramètres audio du média"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Sélectionner un profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Perso"</string>
<string name="category_work" msgid="4014193632325996115">"Pro"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Options pour les développeurs"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les développeurs"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ce téléphone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Cette tablette"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de lire du contenu sur cet appareil"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à niveau le compte pour changer"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Impossible de lire les téléchargements ici"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Réessayez après l\'annonce"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Activer l\'appareil pour lire du contenu ici"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Activez l\'appareil pour lire du contenu ici"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Appareil non autorisé à lire du contenu"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Impossible de lire ce contenu multimédia ici"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 99828995b757..89145cbb1697 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio en HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiófonos"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Audio de baixo consumo"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audiófonos"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Estableceuse conexión co audio de baixo consumo"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao audio multimedia"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A vinculación garante acceso aos teus contactos e ao historial de chamadas ao estar conectado"</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque a clave de acceso ou o PIN son incorrectos."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, clave de acceso ou PIN incorrectos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Non se pode comunicar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vinculación rexeitada por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Ordenador"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Escoller perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Persoal"</string>
<string name="category_work" msgid="4014193632325996115">"Traballo"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clonar"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opcións para programadores"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Activar opcións para programadores"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Definir as opcións de desenvolvemento de aplicacións"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Esta tableta"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Non se pode reproducir contido neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string>
@@ -590,7 +594,7 @@
<string name="user_add_user_type_title" msgid="551279664052914497">"Engadir"</string>
<string name="user_new_user_name" msgid="60979820612818840">"Novo usuario"</string>
<string name="user_new_profile_name" msgid="2405500423304678841">"Novo perfil"</string>
- <string name="user_info_settings_title" msgid="6351390762733279907">"Información usuario"</string>
+ <string name="user_info_settings_title" msgid="6351390762733279907">"Información do usuario"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"Información do perfil"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Para poder crear un perfil restrinxido, precisarás configurar un bloqueo da pantalla para protexer as túas aplicacións e datos persoais."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Establecer bloqueo"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index e2c4954a43a7..fbcc84a79c2a 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"ડિસ્કનેક્ટ થઈ રહ્યું છે..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"કનેક્ટ થઈ રહ્યું છે…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"જોડી કરી રહ્યું છે…"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"જોડાણ કરી રહ્યાં છીએ…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ ફોન નથી)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (કોઈ મીડિયા નથી)"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> સાથે કનેક્ટ થયેલ (ફોન કે મીડિયા નથી)"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ઑડિયો: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ઑડિયો"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"શ્રવણ યંત્રો"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ઑડિયો"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"શ્રવણ યંત્રો સાથે કનેક્ટ કરેલું છે"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ઑડિયોથી કનેક્ટેડ"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"મીડિયા ઑડિઓ સાથે કનેક્ટ કર્યુ"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"પ્રોફાઇલ પસંદ કરો"</string>
<string name="category_personal" msgid="6236798763159385225">"વ્યક્તિગત"</string>
<string name="category_work" msgid="4014193632325996115">"ઑફિસ"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ક્લોન કરો"</string>
<string name="development_settings_title" msgid="140296922921597393">"ડેવલપરના વિકલ્પો"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"વિકાસકર્તાનાં વિકલ્પો સક્ષમ કરો"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ઍપ્લિકેશન વિકાસ માટે વિકલ્પો સેટ કરો"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"હમણાં જ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"આ ફોન"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"આ ટૅબ્લેટ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"આ ફોન"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"આ ડિવાઇસ પર ચલાવી શકતા નથી"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"સ્વિચ કરવા માટે એકાઉન્ટ અપગ્રેડ કરો"</string>
@@ -578,7 +582,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"પ્રતિબંધિત પ્રોફાઇલ"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"તમે વધારાના વપરાશકર્તાઓ બનાવીને અન્ય લોકો સાથે આ ડિવાઇસને શેર કરી શકો છો. દરેક વપરાશકર્તા પાસે તેમની પોતાની સ્પેસ છે, જેને તેઓ ઍપ, વૉલપેપર, વગેરે સાથે કસ્ટમાઇઝ કરી શકે છે. વપરાશકર્તાઓ પ્રત્યેક વ્યક્તિને અસર કરતી હોય તેવી ડિવાઇસ સેટિંગ જેમ કે વાઇ-ફાઇને પણ સમાયોજિત કરી શકે છે.\n\nજ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમની સ્પેસ સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે. નવા વપરાશકર્તાને ઍક્સેસિબિલિટી સેટિંગ અને સેવાઓ ટ્રાન્સફર ન પણ થાય."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ અપ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમની સ્પેસ સેટ અપ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"આ વપરાશકર્તાને ઍડમિન બનાવવા છે?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"ઍડમિન પાસે વિશિષ્ટ વિશેષાધિકારો હોય છે જે અન્ય વપરાશકર્તાઓ પાસે હોતા નથી. ઍડમિન બધા વપરાશકર્તાઓને મેનેજ કરી શકે, આ ડિવાઇસને અપડેટ અથવા રીસેટ કરી શકે, સેટિંગમાં ફેરફાર કરી શકે, ઇન્સ્ટૉલ કરેલી બધી ઍપ જોઈ શકે અને અન્ય લોકોને ઍડમિનના અધિકારો આપી શકે અથવા તેમને રદબાતલ કરી શકે."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ઍડમિન બનાવો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 57a055b9f93f..a123a854a529 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -214,7 +214,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"प्रोफ़ाइल चुनें"</string>
<string name="category_personal" msgid="6236798763159385225">"निजी"</string>
- <string name="category_work" msgid="4014193632325996115">"वर्क"</string>
+ <string name="category_work" msgid="4014193632325996115">"वर्क ऐप्लिकेशन"</string>
<string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
<string name="development_settings_title" msgid="140296922921597393">"डेवलपर के लिए सेटिंग और टूल"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"डेवलपर के लिए सेटिंग और टूल चालू करें"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"अभी-अभी"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"यह फ़ोन"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"यह टैबलेट"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"यह फ़ोन"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"इस डिवाइस पर मीडिया नहीं चलाया जा सकता"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"प्रीमियम खाते में स्विच करने के लिए, अपना खाता अपग्रेड करें"</string>
@@ -578,7 +584,7 @@
<string name="user_add_user_message_long" msgid="1527434966294733380">"नए उपयोगकर्ता जोड़कर इस डिवाइस को दूसरे लोगों के साथ शेयर किया जा सकता है. हर उपयोगकर्ता के पास अपनी जगह होती है, जिसमें वे ऐप्लिकेशन, वॉलपेपर, और दूसरी चीज़ों में मनमुताबिक बदलाव कर सकते हैं. उपयोगकर्ता, वाई-फ़ाई जैसी डिवाइस सेटिंग में भी बदलाव कर सकते हैं. इसका असर हर किसी पर पड़ता है.\n\nजब किसी नए उपयोगकर्ता को जोड़ा जाता है, तो उसे अपनी जगह सेट अप करनी होती है.\n\nकोई भी उपयोगकर्ता, दूसरे सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है. ऐसा भी हो सकता है कि सुलभता सेटिंग और सेवाएं नए उपयोगकर्ता को ट्रांसफ़र न हो पाएं."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"कोई नया उपयोगकर्ता जोड़ने पर, उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता, बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"क्या इस व्यक्ति को एडमिन बनाना है?"</string>
- <string name="user_grant_admin_message" msgid="1673791931033486709">"एडमिन, अन्य लोगों के मुकाबले खास अधिकार होते हैं. एडमिन के पास ये अधिकार होते हैं: सभी लोगों को मैनेज करना, इस डिवाइस को अपडेट या रीसेट करना, सेटिंग में बदलाव करना, इंस्टॉल किए गए सभी ऐप्लिकेशन देखना, और अन्य लोगों को एडमिन के खास अधिकार देना या उन्हें वापस लेना."</string>
+ <string name="user_grant_admin_message" msgid="1673791931033486709">"एडमिन के पास अन्य लोगों के मुकाबले खास अधिकार होते हैं. एडमिन के पास ये अधिकार होते हैं: सभी लोगों को मैनेज करना, इस डिवाइस को अपडेट या रीसेट करना, सेटिंग में बदलाव करना, इंस्टॉल किए गए सभी ऐप्लिकेशन देखना, और अन्य लोगों को एडमिन के खास अधिकार देना या उन्हें वापस लेना."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"एडमिन बनाएं"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"उपयोगकर्ता को अभी सेट करें?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"पक्का करें कि व्यक्ति डिवाइस का इस्तेमाल करने और अपनी जगह सेट करने के लिए मौजूद है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8649e22c6d22..4566cadd162a 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -545,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Upravo sad"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nije moguće reproducirati na ovom uređaju"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun radi prebacivanja"</string>
- <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Preuzimanja se ne mogu reproducirati ovdje"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne može se reproducirati ovdje"</string>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite i prebacite se"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ne može se tu reproducirati"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Pokušajte ponovo nakon oglasa"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Aktivirajte uređaj da biste na njemu reproducirali"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Uređaj nije odobren za reprodukciju"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Ti se mediji ne mogu reproducirati ovdje"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Aktivirajte i reproducirajte ovdje"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Nije odobreno za reprodukciju"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Nemoguća je reprodukcija medija"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audiouređaj"</string>
<string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 7dc9bed72dc2..b9f9d799099b 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hallókészülékek"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Alacsony energiaszintű hangátvitel"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Hallókészülékhez csatlakoztatva"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Csatlakoztatva az alacsony energiaszintű hangátvitelhez"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Csatlakoztatva az eszköz hangjához"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Mégse"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A párosítás hozzáférést biztosít a névjegyekhez és híváselőzményekhez összekapcsolt állapotban."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nem lehet párosítani a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"A párosítás sikertelen volt a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel hibás PIN-kód vagy jelszó miatt."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Sikertelen párosítás a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel – hibás PIN vagy jelszó"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nem lehet kommunikálni a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"A(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszköz elutasította a párosítást."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Számítógép"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profil kiválasztása"</string>
<string name="category_personal" msgid="6236798763159385225">"Személyes"</string>
<string name="category_work" msgid="4014193632325996115">"Munkahelyi"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klónozás"</string>
<string name="development_settings_title" msgid="140296922921597393">"Fejlesztői beállítások"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Fejlesztői beállítások engedélyezése"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Alkalmazásfejlesztési beállítások megadása"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Az imént"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ez a telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ez a táblagép"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ez a telefon"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nem lehet tartalmat lejátszani ezen az eszközön"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"A váltáshoz frissítse fiókját magasabb kategóriára"</string>
- <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Itt nem lehet lejátszani a letöltött elemeket"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nem játszható le ezen az eszközön"</string>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"A váltáshoz frissítse fiókját"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Itt nem játszhatók le a letöltések"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Próbálja újra a hirdetés után"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"A tartalom itteni lejátszásához ébressze fel az eszközt"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Az eszköz nem játszhat le tartalmat"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"A médiatartalom nem játszható le itt"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Lejátszáshoz ébressze fel az eszközt"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Az eszköz nem játszhat le"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"A tartalom nem játszható le itt"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vezetékes audioeszköz"</string>
<string name="help_label" msgid="3528360748637781274">"Súgó és visszajelzés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0fc853edbde7..de002a0c17dd 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD աուդիո"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Լսողական ապարատ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Լսողական ապարատը միացված է"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Միացած է LE audio-ին"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Միացված է մեդիա աուդիոյին"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Ընտրեք պրոֆիլ"</string>
<string name="category_personal" msgid="6236798763159385225">"Անձնական"</string>
<string name="category_work" msgid="4014193632325996115">"Աշխատանքային"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Կլոն"</string>
<string name="development_settings_title" msgid="140296922921597393">"Մշակողի ընտրանքներ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Միացնել մշակողի ընտրանքները"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Կարգավորել ընտրանքները ծրագրի ծրագրավորման համար"</string>
@@ -547,10 +545,16 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Հենց նոր"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Այս հեռախոսը"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Այս պլանշետը"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Այս հեռախոսը"</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>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ներբեռնումները չեն նվագարկվում այստեղ"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Նորից փորձեք գովազդից հետո"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Արթնացրեք սարքը՝ այստեղ նվագարկելու համար"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Նվագարկելու համար հաստատեք սարքը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7af9ca85bb16..cdc297e21df0 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Batal"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Penyandingan memberi akses ke kontak dan histori panggilan saat terhubung"</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Tidak dapat menyambungkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Tidak dapat menyambungkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> karena PIN atau kode sandi salah."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN atau kunci sandi salah. Penyambungan ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gagal."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Tidak dapat berkomunikasi dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Penyandingan ditolak oleh <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Komputer"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Baru saja"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ponsel ini"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tablet ini"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ponsel ini"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat memutar di perangkat ini"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade akun untuk beralih"</string>
@@ -670,7 +676,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"Keyboard fisik"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Pilih tata letak keyboard"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"Mengaktifkan layar"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"Pengaktifan layar"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Izinkan pengaktifan layar"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Mengizinkan aplikasi mengaktifkan layar. Jika diizinkan, aplikasi dapat mengaktifkan layar kapan saja tanpa izin Anda."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 5e443f6ec283..18acafd412df 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-hljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-hljóð"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Heyrnartæki"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-hljóð"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Tengt við heyrnartæki"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Tengt við LE-hljóð"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Tengt við hljóðspilun efnis"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Veldu snið"</string>
<string name="category_personal" msgid="6236798763159385225">"Persónulegt"</string>
<string name="category_work" msgid="4014193632325996115">"Vinna"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Afrit"</string>
<string name="development_settings_title" msgid="140296922921597393">"Forritunarkostir"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Virkja valkosti þróunaraðila"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Stilla valkosti fyrir forritaþróun"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Rétt í þessu"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Þessi sími"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Þessi spjaldtölva"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Þessi sími"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ekki er hægt að spila í þessu tæki"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppfærðu reikninginn til að skipta"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 9c28102c5ae8..7e84c5a9b21a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Connessione…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> Connesso"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento…"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Accoppiamento in corso…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono escluso)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (contenuti multimediali esclusi)"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> connesso (telefono o media esclusi)"</string>
@@ -99,8 +99,8 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"S: batteria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: batteria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Attivo"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Attivo, solo sinistra"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Attivo, solo destra"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Attiva, solo sinistra"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Attiva, solo destra"</string>
<string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Attivo, destra e sinistra"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimediale"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonate"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Adesso"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Questo telefono"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Questo tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo telefono"</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>
@@ -575,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Utente"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Profilo con limitazioni"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Aggiungere un nuovo utente?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Puoi condividere il dispositivo con altre persone creando altri utenti. Ogni utente ha un proprio spazio personalizzabile con app, sfondo e così via. Gli utenti possono anche regolare le impostazioni del dispositivo, come il Wi‑Fi, che riguardano tutti.\n\nQuando crei un nuovo utente, la persona in questione deve configurare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri utenti. I servizi e le impostazioni di accessibilità non potranno essere trasferiti al nuovo utente."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Puoi condividere il dispositivo con altre persone creando altri utenti. Ogni utente ha un proprio spazio personalizzabile con app, sfondo e così via. Gli utenti possono anche regolare le impostazioni del dispositivo, come il Wi‑Fi, che riguardano tutti.\n\nQuando crei un nuovo utente, la persona in questione deve configurare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri utenti. È possibile che i servizi e le impostazioni di accessibilità non vengano trasferiti al nuovo utente."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Il nuovo utente, una volta aggiunto, deve configurare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Vuoi impostare questo utente come amministratore?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Gli amministratori hanno privilegi speciali che altri utenti non hanno. Un amministratore può gestire tutti gli utenti, aggiornare o resettare questo dispositivo, modificare le impostazioni, vedere tutte le app installate e concedere o revocare privilegi amministrativi per altri utenti."</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 1caad2c6e7f1..c772f375c915 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -545,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"הרגע"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"הטלפון הזה"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"הטאבלט הזה"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"אפשר לנסות שוב לאחר המודעה"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"צריך להוציא את המכשיר ממצב השינה כדי להפעיל כאן"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"המכשיר לא קיבל אישור להפעלה"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"אי אפשר להפעיל את המדיה הזו כאן"</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>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"יש לנסות אחרי המודעה"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"צריך להעיר את המכשיר"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"המכשיר לא אושר"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"אי אפשר להפעיל מדיה"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"יש בעיה בחיבור. עליך לכבות את המכשיר ולהפעיל אותו מחדש"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"התקן אודיו חוטי"</string>
<string name="help_label" msgid="3528360748637781274">"עזרה ומשוב"</string>
@@ -575,8 +581,8 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"משתמש"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"פרופיל מוגבל"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"להוסיף משתמש חדש?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"‏ניתן לשתף מכשיר זה עם אנשים אחרים על ידי יצירת משתמשים נוספים. לכל משתמש מרחב משלו, שאותו אפשר להתאים אישית בעזרת אפליקציות, טפט ופריטים נוספים. המשתמשים יכולים גם להתאים הגדרות של המכשיר כגון Wi‑Fi, שמשפיעות על כולם.\n\nכשמוסיפים משתמש חדש, על משתמש זה להגדיר את המרחב שלו.\n\nכל אחד מהמשתמשים יכול לעדכן אפליקציות לכל שאר המשתמשים. ייתכן שהגדרות ושירותים של נגישות לא יועברו למשתמש החדש."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את המרחב שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"‏ניתן לשתף את המכשיר הזה עם אנשים אחרים על ידי יצירת משתמשים נוספים. לכל משתמש מרחב משלו, שאותו אפשר להתאים אישית בעזרת אפליקציות, טפט ופריטים נוספים. המשתמשים יכולים גם להתאים הגדרות של המכשיר כמו Wi‑Fi, שמשפיעות על כולם.\n\nכשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את המרחב שלו.\n\nכל אחד מהמשתמשים יכול לעדכן אפליקציות לכל שאר המשתמשים. יכול להיות שהגדרות ושירותים של נגישות לא יועברו למשתמש החדש."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"כשמוסיפים משתמש חדש, הוא צריך להגדיר את המרחב שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"להגדיר את המשתמש הזה כאדמין?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"לאדמינים יש הרשאות מיוחדות שאין למשתמשים אחרים. אדמין יכול לנהל את כל המשתמשים, לעדכן את המכשיר הזה או לאפס אותו, לשנות הגדרות, לראות את כל האפליקציות המותקנות ולהעניק הרשאות אדמין לאחרים או לשלול אותן."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"הגדרה כאדמין"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 032046811603..a459abfe2429 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -543,16 +543,22 @@
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"毎回確認"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"OFF にするまで"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"たった今"</string>
- <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"このスマートフォン"</string>
+ <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"このデバイス"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"このタブレット"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"このスマートフォン"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"このデバイスで再生できません"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"広告が表示されてから、もう一度試してください"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ここで再生するにはデバイスを起動してください"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"このデバイスでの再生が許可されていません"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"このメディアはここで再生できません"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"再生不可: ダウンロードしたコンテンツ"</string>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"広告の後にもう一度試してください"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"デバイスの起動が必要です"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"再生が許可されていません"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"このメディアは再生できません"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
<string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 115260966a67..147512b2cc20 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -545,10 +545,13 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ახლახან"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ეს ტელეფონი"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ეს ტაბლეტი"</string>
+ <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"დინამიკის სამაგრი"</string>
+ <string name="media_transfer_external_device_name" msgid="2588672258721846418">"გარე მოწყობილობა"</string>
+ <string name="media_transfer_default_device_name" msgid="4315604017399871828">"დაკავშირებული მოწყობილობა"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ეს ტელეფონი"</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>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"შეუძლებელია აქ ჩამოტვირ. თამაში"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"სცადეთ ხელახლა რეკლამის შემდეგ"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"დასაკრავად გამოაღვიძეთ ტელეფონი"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"მოწყობილობა არ არის ავტორიზებული დასაკრავად"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 0fa9996fbc4d..83388a09b3b6 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD форматты аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD форматты аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Есту аппараттары"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Есту аппараттарына жалғанған"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio-ға жалғанды."</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиосына жалғанған"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Профильді таңдау"</string>
<string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
<string name="category_work" msgid="4014193632325996115">"Жұмыс"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клондау"</string>
<string name="development_settings_title" msgid="140296922921597393">"Әзірлеуші опциялары"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Әзірлеуші ​​параметрлерін қосу"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Қолданба дамыту үшін опцияларын реттеу"</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Дәл қазір"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Осы телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Осы планшет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Осы телефон"</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>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Жарнамадан кейін қайталап көріңіз."</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Осы жерде ойнату үшін құрылғыны оятыңыз."</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Осы жерде ойнату үшін құрылғыны ұйқы режимінен шығарыңыз."</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Ойнату үшін авторизация керек."</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Бұл мультимедиа файлын осы жерде ойнату мүмкін емес."</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Байланыс орнату қатесі шығуып жатыр. Құрылғыны өшіріп, қайта қосыңыз."</string>
@@ -577,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Пайдаланушы"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Шектелген профайл"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Жаңа пайдаланушы қосылсын ба?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Қосымша профильдер жасай отырып, бұл құрылғыны басқалармен ортақ пайдалануға болады. Әр пайдаланушы қолданбаларды, тұсқағаздарды орнатып, профилін өз қалауынша реттей алады. Сондай-ақ барлығы ортақ қолданатын Wi‑Fi сияқты параметрлерді де реттеуге болады.\n\nЖаңа пайдаланушы енгізілгенде, ол өз профилін реттеуі керек болады.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады. Арнайы мүмкіндіктерге қатысты параметрлер мен қызметтер жаңа пайдаланушыға өтпейді."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Қосымша пайдаланушылар жасай отырып, бұл құрылғыны басқалармен бөлісуге болады. Әр пайдаланушы қолданбалар, тұсқағаздар орнатып, профилін қалауынша реттей алады. Барлық пайдаланушы қолданатын Wi‑Fi сияқты параметрлерді де реттеуге болады.\n\nЖаңа пайдаланушы қосылғанда, ол өз профилін реттеуі керек.\n\nКез келген пайдаланушы басқа пайдаланушылар үшін қолданбаларды жаңарта алады. Арнайы мүмкіндіктерге қатысты параметрлер мен қызметтер жаңа пайдаланушыға берілмейді."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Жаңадан қосылған пайдаланушы өз профилін реттеуі керек.\n\nКез келген пайдаланушы басқалар үшін қолданбаларды жаңарта алады."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Осы пайдаланушыны әкімші ету керек пе?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Әкімшілер басқа пайдаланушыларда болмайтын арнайы өкілеттерге ие. Әкімші мына әрекеттерді орындай алады: барлық пайдаланушыны басқару, осы құрылғыны жаңарту не бастапқы күйге қайтару, параметрлерді өзгерту, орнатылған құрылғының барлығын көру және әкімші өкілеттерін басқа пайдаланушыларға беру не қайтару."</string>
@@ -613,8 +617,8 @@
<string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Мұндайда жаңа қонақ сеансы басталады және ағымдағы сеанстағы барлық қолданба мен дерек жойылады."</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Қонақ режимінен шығу керек пе?"</string>
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ағымдағы қонақ сеансындағы барлық қолданба мен дерек жойылады."</string>
- <string name="grant_admin" msgid="4323199171790522574">"Иә, пайдаланушы әкімші етілсін"</string>
- <string name="not_grant_admin" msgid="3557849576157702485">"Жоқ, пайдаланушы әкімші етілмесін"</string>
+ <string name="grant_admin" msgid="4323199171790522574">"Иә, әкімші болсын"</string>
+ <string name="not_grant_admin" msgid="3557849576157702485">"Жоқ, әкімші болмасын"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Шығу"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Қонақ әрекетін сақтау керек пе?"</string>
<string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ағымдағы сеанс тарихын сақтауға не барлық қолданба мен деректі жоюға болады."</string>
@@ -674,7 +678,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Әдепкі"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Экранды қосу"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Экранды қосуға рұқсат беру"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Қолданбаның экранды қосуына рұқсат береді. Рұқсат берілсе, қолданба кез келген уақытта экранды өздігінен қосуы мүмкін."</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Қолданбаға экранды қосуға рұқсат береді. Рұқсат берілсе, қолданба кез келген уақытта экранды өздігінен қосуы мүмкін."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index e546821e1adc..0e470f51d433 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -545,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"អម្បាញ់មិញ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ទូរសព្ទនេះ"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ថេប្លេតនេះ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ទូរសព្ទនេះ"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"ព្យាយាមម្ដងទៀត បន្ទាប់ពីការផ្សាយពាណិជ្ជកម្ម"</string>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"ព្យាយាមម្ដងទៀត បន្ទាប់ពីពាណិជ្ជកម្ម"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ដាស់ឧបករណ៍ឱ្យចាក់នៅទីនេះ"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ឧបករណ៍មិន​យល់ព្រមឱ្យចាក់ទេ"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ឧបករណ៍មិន​ព្រមឱ្យចាក់ទេ"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"មិនអាចចាក់មេឌៀនេះ​នៅទីនេះបានទេ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"មាន​បញ្ហា​ក្នុងការ​ភ្ជាប់។ បិទ រួច​បើក​ឧបករណ៍​វិញ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ឧបករណ៍​សំឡេងប្រើខ្សែ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 16cbbeea71e6..9b05c6ec8d41 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -49,7 +49,7 @@
<string name="wifi_security_none_owe" msgid="5241745828327404101">"ಯಾವುದೂ ಇಲ್ಲ/Enhanced Open"</string>
<string name="wifi_security_owe" msgid="3343421403561657809">"Enhanced Open"</string>
<string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-ಎಂಟರ್‌ಪ್ರೈಸ್ 192-ಬಿಟ್"</string>
- <string name="wifi_remembered" msgid="3266709779723179188">"ಉಳಿಸಲಾಗಿದೆ"</string>
+ <string name="wifi_remembered" msgid="3266709779723179188">"ಸೇವ್‌ ಮಾಡಲಾಗಿದೆ"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP ಕಾನ್ಫಿಗರೇಶನ್ ವಿಫಲತೆ"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ಆಡಿಯೋ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ಆಡಿಯೋ"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ಶ್ರವಣ ಸಾಧನಗಳಿಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ಆಡಿಯೋಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ಮಾಧ್ಯಮ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ರದ್ದುಮಾಡಿ"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ಸಂಪರ್ಕಗೊಳಿಸಿದಾಗ, ಜೋಡಿಸುವಿಕೆಯು ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಣೆ ಮಾಡಲಾಗಲಿಲ್ಲ."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ತಪ್ಪಾಗಿರುವ ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ತಪ್ಪು ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲಾಗಲಿಲ್ಲ."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"ಜೋಡಿಸುವಿಕೆಯನ್ನು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ತಿರಸ್ಕರಿಸಿದೆ"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"ಕಂಪ್ಯೂಟರ್‌"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="category_personal" msgid="6236798763159385225">"ವೈಯಕ್ತಿಕ"</string>
<string name="category_work" msgid="4014193632325996115">"ಕೆಲಸ"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ಕ್ಲೋನ್"</string>
<string name="development_settings_title" msgid="140296922921597393">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ಅಪ್ಲಿಕೇಶನ್ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
@@ -322,7 +320,7 @@
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ವೈ-ಫೈ ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್‌ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್‌ವರ್ಕ್‌ ಬದಲಾಯಿಸಲು)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆ ಟೆಥರಿಂಗ್ ಲಭ್ಯವಿದ್ದರೆ ಅದನ್ನು ಬಳಸಿ"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
- <string name="adb_warning_message" msgid="8145270656419669221">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
+ <string name="adb_warning_message" msgid="8145270656419669221">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ನೋಟಿಫಿಕೇಶನ್ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆ್ಯಪ್‍ಗಳನ್ನು ಇನ್‍ಸ್ಟಾಲ್ ಮಾಡಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸಬೇಕೆ?"</string>
<string name="adbwifi_warning_message" msgid="8005936574322702388">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್‌ಗಳಿಂದ USB ಡೀಬಗ್‌ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
@@ -395,7 +393,7 @@
<string name="app_process_limit_title" msgid="8361367869453043007">"ಹಿನ್ನೆಲೆ ಪ್ರಕ್ರಿಯೆ ಮಿತಿ"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"ಹಿನ್ನೆಲೆ ANR ಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸಿ"</string>
- <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ಅಧಿಸೂಚನೆ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string>
+ <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ನೋಟಿಫಿಕೇಶನ್ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ಅಮಾನ್ಯ ಚಾನಲ್ ಅಧಿಸೂಚನೆಗಾಗಿ ಪರದೆಯಲ್ಲಿ ಎಚ್ಚರಿಕೆ"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string>
@@ -547,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ಇದೀಗ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ಈ ಫೋನ್"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ಈ ಟ್ಯಾಬ್ಲೆಟ್"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ಈ ಫೋನ್"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"ಜಾಹೀರಾತಿನ ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"ಆ್ಯಡ್‌ನ ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಸಾಧನವನ್ನು ಎಚ್ಚರಿಸಿ"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ಸಾಧನವನ್ನು ಪ್ಲೇ ಮಾಡಲು ಅನುಮೋದಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ಪ್ಲೇ ಮಾಡಲು ಸಾಧನವನ್ನು ಅನುಮೋದಿಸಲಾಗಿಲ್ಲ"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"ಈ ಮಾಧ್ಯಮವನ್ನು ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ಕನೆಕ್ಟ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ ಸಾಧನವನ್ನು ಆಫ್ ಮಾಡಿ ಹಾಗೂ ನಂತರ ಪುನಃ ಆನ್ ಮಾಡಿ"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ವೈರ್ ಹೊಂದಿರುವ ಆಡಿಯೋ ಸಾಧನ"</string>
@@ -576,9 +580,9 @@
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"ನಿಮ್ಮ ಖಾತೆಯಿಂದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ವಿಷಯಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ನೀವು ನಿರ್ಬಂಧಿಸಬಹುದು"</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"ಬಳಕೆದಾರ"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"ನಿರ್ಬಂಧಿಸಿದ ಪ್ರೊಫೈಲ್"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"ಈ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಬೇಕೆ?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"ನಿರ್ವಾಹಕರು ಇತರ ಬಳಕೆದಾರರಿಗೆ ಇಲ್ಲದ ವಿಶೇಷ ಸೌಲಭ್ಯಗಳನ್ನು ಹೊಂದಿದ್ದಾರೆ. ನಿರ್ವಾಹಕರು ಎಲ್ಲಾ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಬಹುದು, ಈ ಸಾಧನವನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು ಅಥವಾ ರೀಸೆಟ್ ಮಾಡಬಹುದು, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಹೊಂದಿಸಬಹುದು, ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ಇತರರಿಗೆ ನಿರ್ವಾಹಕರಿಗೆ ನೀಡಿರುವ ಸೌಲಭ್ಯಗಳನ್ನು ನೀಡಬಹುದು ಅಥವಾ ಹಿಂತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 774d434582e5..273176ce17dc 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD 오디오: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD 오디오"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"보청기"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE 오디오"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"보청기에 연결됨"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE 오디오에 연결됨"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"미디어 오디오에 연결됨"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"프로필 선택"</string>
<string name="category_personal" msgid="6236798763159385225">"개인"</string>
<string name="category_work" msgid="4014193632325996115">"직장"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"복사"</string>
<string name="development_settings_title" msgid="140296922921597393">"개발자 옵션"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"개발자 옵션 사용"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"앱 개발 옵션 설정"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"조금 전"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"이 휴대전화"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"태블릿"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"이 휴대전화"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"이 기기에서 재생할 수 없음"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"전환하려면 계정을 업그레이드하세요."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 9902d94a69e4..e2495d08e4e0 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -99,7 +99,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Сол: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, оң: Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Жигердүү"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Жигердүү, сол кулакчын гана"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Иштеп жатат, сол кулак гана"</string>
<string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Жигердүү, оң кулакчын гана"</string>
<string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Жигердүү, сол жана оң кулакчын"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аудио"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD форматындагы аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD форматындагы аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Угуу аппараттары"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Угуу аппараттарына туташып турат"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE аудио менен туташты"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиого туташты"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Жок"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө туташуу мүмкүн болгон жок."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN-код же сырсөз туура эмес болгондуктан, \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" туташпай калды."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"\"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" туташкан жок: PIN код же сырсөз туура эмес."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышуу мүмкүн эмес."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Жупташтырууну <xliff:g id="DEVICE_NAME">%1$s</xliff:g> четке какты."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компьютер"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Профиль тандоо"</string>
<string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
<string name="category_work" msgid="4014193632325996115">"Жумуш"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Иштеп чыгуучунун параметрлери"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Иштеп чыгуучунун параметрлерин иштетүү"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Колдонмо өндүрүү мүмкүнчүлүктөрүн орнотуу"</string>
@@ -248,12 +246,12 @@
<string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi аркылуу байланыштыруу коду"</string>
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Туташкан жок"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Түзмөк бир тармакка туташып турушу керек."</string>
- <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
+ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодду скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
<string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Түзмөк жупташтырылууда…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Түзмөк жупташтырылган жок. QR коду туура эмес же түзмөк бир тармакка туташпай турат."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP дарек жана порт"</string>
- <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR кодун скандоо"</string>
- <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
+ <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR кодду скандоо"</string>
+ <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR кодду скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string>
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi тармагына туташыңыз"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, мүчүлүштүктөрдү оңдоо, иштеп чыгуу"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Ката жөнүндө кабарлоо"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Жаңы эле"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ушул телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ушул планшет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</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>
- <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Жарнамадан кийин кайталап көрүңүз"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Угуу үчүн түзмөктү уйку режиминен чыгарыңыз"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Бул түзмөктө ойнотуу үчүн уруксат алуу керек"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Бул медианы ойнотуу мүмкүн эмес"</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>
+ <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Жарнамадан кийин кайталаңыз"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Угуу үчүн түзмөктү уйкудан чыгарыңыз"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Ойнотуу үчүн уруксат алышыңыз керек"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Медиа файлды ойното албайсыз"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Туташууда маселе келип чыкты. Түзмөктү өчүрүп, кайра күйгүзүп көрүңүз"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Зымдуу аудио түзмөк"</string>
<string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 1b7138db7172..25466d4c91e5 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ຕອນນີ້"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ໂທລະສັບນີ້"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ແທັບເລັດນີ້"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ໂທລະສັບນີ້"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ຫຼິ້ນຢູ່ອຸປະກອນນີ້ບໍ່ໄດ້"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ອັບເກຣດບັນຊີເພື່ອສະຫຼັບ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index cde94bb600f2..ff9f1c294c5a 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD garsas: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD garsas"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Klausos aparatai"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Prisijungta prie klausos aparatų"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Prisijungta prie „LE Audio“"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Prijungta prie medijos garso įrašo"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profilio pasirinkimas"</string>
<string name="category_personal" msgid="6236798763159385225">"Asmeninės"</string>
<string name="category_work" msgid="4014193632325996115">"Darbo"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Identiška kopija"</string>
<string name="development_settings_title" msgid="140296922921597393">"Kūrėjo parinktys"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Įgalinti kūrėjo parinktis"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Nustatyti programos kūrimo parinktis"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Ką tik"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Šis telefonas"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Šis planšetinis kompiuteris"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis telefonas"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Negalima leisti šiame įrenginyje"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Jei norite perjungti, naujovinkite paskyrą"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index a9cc964f5908..91051539f2ad 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -106,7 +106,7 @@
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Tālruņa zvani"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failu pārsūtīšana"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ievades ierīce"</string>
- <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneta piekļuve"</string>
+ <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Piekļuve internetam"</string>
<string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Kontaktpersonu un zvanu vēst. kopīgošana"</string>
<string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Paredzēts kontaktpersonu un zvanu vēstures kopīgošanai"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneta savienojuma koplietošana"</string>
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Atcelt"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Veicot savienošanu pārī, šī ierīce savienojuma laikā varēs piekļūt jūsu kontaktpersonām un zvanu vēsturei."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nevarēja savienot pārī ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nevarēja savienot pārī ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, jo tika ievadīts nepareizs PIN kods vai nepareiza ieejas atslēga."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nevarēja savienot pārī ar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, jo tika ievadīts nepareizs PIN kods vai ieejas atslēga."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nevar sazināties ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> noraidīja pāra izveidi."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Dators"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Tikko"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Šis tālrunis"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Šis planšetdators"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis tālrunis"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nevar atskaņot šajā ierīcē."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Lai pārslēgtu, jauniniet kontu"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index cb69faf71eed..0005ec5175dc 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слушни помагала"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-аудио"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Поврзано со слушни помагала"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Поврзано на LE-аудио"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Поврзан со аудио на медиуми"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Изберете профил"</string>
<string name="category_personal" msgid="6236798763159385225">"Лични"</string>
<string name="category_work" msgid="4014193632325996115">"Работа"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Програмерски опции"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Овозможете ги програмерските опции"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Постави опции за развој на апликација"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Пред малку"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Овој телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Овој таблет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Овој телефон"</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>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Обидете се повторно по рекламата"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Разбудете го уредот за да пуштате овде"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Разбудете го уредот за да пуштате тука"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Уредот не е одобрен за репродукција"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Не може да се пуштат аудиовизуелните содржини овде"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Овие аудиовизуелни содржини не може да се пуштат тука"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем со поврзување. Исклучете го уредот и повторно вклучете го"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичен аудиоуред"</string>
<string name="help_label" msgid="3528360748637781274">"Помош и повратни информации"</string>
@@ -579,9 +583,9 @@
<string name="user_add_user_title" msgid="5457079143694924885">"Да се додаде нов корисник?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Уредов може да го споделувате со други лица ако додадете дополнителни корисници. Секој корисник има сопствен простор што може да го приспособува со апликации, тапети и слично. Корисниците може да приспособуваат и поставки за уредот, како на пр., Wi‑Fi, што важат за сите.\n\nКога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници. Поставките и услугите за пристапност не може да се префрлат на новиот корисник."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
- <string name="user_grant_admin_title" msgid="5157031020083343984">"Дали да се направи корисников администратор?"</string>
- <string name="user_grant_admin_message" msgid="1673791931033486709">"Администраторите имаат посебни привилегии што другите корисници ги немаат. Администраторот може да управува со сите корисници, да го ажурира или ресетира уредов, да ги менува поставките, да ги гледа сите инсталирани апликации и да доделува или одзема администраторски привилегии за други."</string>
- <string name="user_grant_admin_button" msgid="5441486731331725756">"Направи да биде администратор"</string>
+ <string name="user_grant_admin_title" msgid="5157031020083343984">"Да се постави корисников како администратор?"</string>
+ <string name="user_grant_admin_message" msgid="1673791931033486709">"Администраторите имаат посебни привилегии што другите корисници ги немаат. Администраторот може да управува со сите корисници, да го ажурира или ресетира уредов, да ги менува поставките, да ги прегледува сите инсталирани апликации и да доделува или одзема администраторски привилегии на другите корисници."</string>
+ <string name="user_grant_admin_button" msgid="5441486731331725756">"Постави како администратор"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Ќе поставите корисник сега?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Проверете дали лицето е достапно да го земе уредот и да го постави својот простор"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Постави профил сега?"</string>
@@ -613,8 +617,8 @@
<string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Ова ќе започне нова гостинска сесија и ќе ги избрише сите апликации и податоци од тековната сесија"</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Да се излезе од режим на гостин?"</string>
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ова ќе ги избрише апликациите и податоците од тековната гостинска сесија"</string>
- <string name="grant_admin" msgid="4323199171790522574">"Да, направи да биде администратор"</string>
- <string name="not_grant_admin" msgid="3557849576157702485">"Не, не прави да биде администратори"</string>
+ <string name="grant_admin" msgid="4323199171790522574">"Да, постави како администратор"</string>
+ <string name="not_grant_admin" msgid="3557849576157702485">"Не, не поставувај како администратор"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Излези"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Да се зачува гостинската активност?"</string>
<string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Може да ја зачувате активноста од тековната сесија или да ги избришете сите апликации и податоци"</string>
@@ -674,7 +678,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Стандардно"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Вклучување на екранот"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Дозволи вклучување на екранот"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозволете апликација да го вклучи екранот. Ако дозволите, апликацијата може да го вклучи екранот во секое време без ваша намера."</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозволува одредена апликација да го вклучува екранот. Ако е дозволено, апликацијата може да го вклучува екранот во секое време без ваша намера."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 0cb2cc6ac053..12d6e5269725 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ഓഡിയോ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ഓഡിയോ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ശ്രവണ സഹായികൾ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ഓഡിയോ"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ശ്രവണ സഹായികളിലേക്ക് കണക്‌റ്റ് ചെയ്‌തു"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ഓഡിയോയിലേക്ക് കണക്‌റ്റ് ചെയ്‌തു"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"മീഡിയ ഓഡിയോയിലേക്ക് കണ‌ക്റ്റുചെയ്‌തു"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"പ്രൊഫൈൽ തിരഞ്ഞെടുക്കുക"</string>
<string name="category_personal" msgid="6236798763159385225">"വ്യക്തിപരം"</string>
<string name="category_work" msgid="4014193632325996115">"ഔദ്യോഗികം"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ക്ലോൺ ചെയ്യുക"</string>
<string name="development_settings_title" msgid="140296922921597393">"ഡെവലപ്പർ ഓ‌പ്ഷനുകൾ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ഡെവലപ്പർ ഓ‌പ്ഷനുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"അപ്ലിക്കേഷൻ വികസനത്തിന് ഓപ്ഷനുകൾ സജ്ജീകരിക്കുക"</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ഇപ്പോൾ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ഈ ഫോൺ"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ഈ ടാബ്‌ലെറ്റ്"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ഈ ഫോൺ"</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>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"അക്കൗണ്ട് മാറാൻ അപ്‌ഗ്രേഡ് ചെയ്യുക"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ഡൗൺലോഡുകൾ പ്ലേ ചെയ്യാനാകില്ല"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"പരസ്യത്തിന് ശേഷം വീണ്ടും ശ്രമിക്കുക"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ഇവിടെ പ്ലേ ചെയ്യാൻ ഉപകരണം സജീവമാക്കുക"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"പ്ലേ ചെയ്യാൻ ഉപകരണം സജീവമാക്കുക"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"ഉപകരണത്തിന് പ്ലേ ചെയ്യാനുള്ള അനുമതിയില്ല"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"ഈ മീഡിയ ഇവിടെ പ്ലേ ചെയ്യാൻ കഴിയില്ല"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"കണക്‌റ്റ് ചെയ്യുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഉപകരണം ഓഫാക്കി വീണ്ടും ഓണാക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 0e390d455c64..d2e03f2fb8a5 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD аудио"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Сонсголын төхөөрөмж"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Аудио"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Сонсголын төхөөрөмжтэй холбосон"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE аудионд холбогдсон"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиод холбогдсон"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Профайл сонгох"</string>
<string name="category_personal" msgid="6236798763159385225">"Хувийн"</string>
<string name="category_work" msgid="4014193632325996115">"Ажил"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Хөгжүүлэгчийн тохиргоо"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Хөгжүүлэгчийн сонголтыг идэвхжүүлэх"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Апп хөгжүүлэлтэд зориулсан сонголтуудыг тохируулах"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Дөнгөж сая"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Энэ утас"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Энэ таблет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Энэ утас"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Энэ төхөөрөмжид тоглуулах боломжгүй"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Сэлгэхийн тулд бүртгэлийг сайжруулна уу"</string>
@@ -578,7 +582,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Хязгаарлагдсан профайл"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Шинэ хэрэглэгч нэмэх үү?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Та нэмэлт хэрэглэгч үүсгэх замаар бусад хүмүүстэй энэ төхөөрөмжийг хуваалцаж болно. Хэрэглэгч тус бүр апп, дэлгэцийн зураг болон бусад зүйлээ өөрчлөх боломжтой хувийн орон зайтай байна. Түүнчлэн хэрэглэгч нь бүх хэрэглэгчид нөлөөлөх боломжтой Wi-Fi зэрэг төхөөрөмжийн тохиргоог өөрчлөх боломжтой.\n\nХэрэв та шинэ хэрэглэгч нэмэх бол тухайн хүн хувийн орон зайгаа бүрдүүлэх ёстой.\n\nХэрэглэгч бүр бусад бүх хэрэглэгчийн өмнөөс апп шинэчилж болно. Хандалтын тохиргоо болон үйлчилгээг шинэ хэрэглэгчид шилжүүлэх боломжгүй байж болзошгүй."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн орон зайг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бусад бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Энэ хэрэглэгчийг админ болгох уу?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Админууд бусад хэрэглэгчид байхгүй тусгай эрхтэй байдаг. Админ нь бүх хэрэглэгчийг удирдах, энэ төхөөрөмжийг шинэчлэх, сэргээх, тохиргоог өөрчлөх, бүх суулгасан аппыг харах болон бусад хэрэглэгчид админы эрх өгөх эсвэл эрхийг нь цуцлах боломжтой."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Админ болгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index e58ecdb152fd..8c2b4ae4b082 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -545,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"आत्ताच"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"हा फोन"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"हा टॅबलेट"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"हा फोन"</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>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"येथे डाउनलोड प्ले केले जाऊ शकत नाहीत"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"जाहिरातीनंतर पुन्हा प्रयत्न करा"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"येथे प्ले करण्यासाठी डिव्हाइस सुरू करा"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"प्ले करण्यासाठी डिव्हाइस हे मंजुरी दिलेले नाही"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"डिव्हाइसला प्ले करण्यासाठी मंजुरी नाही"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"हा मीडिया येथे प्ले करू शकत नाही"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
@@ -576,7 +582,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबंधित प्रोफाईल"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"नवीन वापरकर्ता जोडायचा?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"अतिरिक्त वापरकर्ते तयार करून तुम्ही इतर लोकांसोबत हे डिव्हाइस शेअर करू शकता. प्रत्येक वापरकर्त्यास त्यांची स्वतःची स्पेस असते, जी ते अ‍ॅप्स, वॉलपेपर आणि यासारख्या गोष्टींनी कस्टमाइझ करू शकतात. वापरकर्ते प्रत्येकाला प्रभावित करणाऱ्या वाय-फाय सारख्या डिव्हाइस सेटिंग्ज अ‍ॅडजस्ट देखील करू शकतात.\n\nतुम्ही एक नवीन वापरकर्ता जोडता, तेव्हा त्या व्यक्तीला त्याची स्पेस सेट अप करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो. अ‍ॅक्सेसिबिलिटी सेटिंग्ज आणि सेवा नवीन वापरकर्त्याला कदाचित ट्रान्सफर होणार नाहीत."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीस त्यांचे स्थान सेट करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"तुम्ही एक नवीन वापरकर्ता जोडता, तेव्हा त्या व्यक्तीस त्यांची स्पेस सेट करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"या वापरकर्त्याला ॲडमिन करायचे का?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"ॲडमिनकडे खास विशेषाधिकार आहेत जे इतर वापरकर्त्यांकडे नसतात. ॲडमिन सर्व वापरकर्ते व्यवस्थापित करू शकतो, हे डिव्हाइस अपडेट करू शकतो किंवा रीसेट करू शकतो, सेटिंग्जमध्ये सुधारणा करू शकतो, सर्व इंस्टॉल केलेली अ‍ॅप्स पाहू शकतो आणि इतरांसाठी ॲडमिनचे विशेषाधिकार मंजूर करू शकतो किंवा रद्द करू शकतो."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ॲडमिन करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 31cd9f324f2c..e991b2428404 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -545,9 +545,15 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Sebentar tadi"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Telefon ini"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tablet ini"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefon ini"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat dimainkan pada peranti ini"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"Tingkatkan akaun untuk bertukar"</string>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"Tingkatkan akaun untuk beralih"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memainkan muat turun di sini"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Cuba lagi selepas iklan"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Bangkitkan peranti untuk main di sini"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index f3827ab14b67..12bd02e553f9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD အသံ- <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD အသံ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"နားကြားကိရိယာ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"နားကြားကိရိယာနှင့် ချိတ်ဆက်ပြီးပါပြီ"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE အသံနှင့် ချိတ်ဆက်ထားသည်"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"မီဒီယာအသံအား ချိတ်ဆက်ရန်"</string>
@@ -214,10 +213,9 @@
<item msgid="6946761421234586000">"၄၀၀%"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"ပရိုဖိုင်ကို ရွေးရန်"</string>
- <string name="category_personal" msgid="6236798763159385225">"ကိုယ်ရေး"</string>
+ <string name="category_personal" msgid="6236798763159385225">"ကိုယ်ပိုင်"</string>
<string name="category_work" msgid="4014193632325996115">"အလုပ်"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ပုံတူပွားရန်"</string>
<string name="development_settings_title" msgid="140296922921597393">"ဆော့ဝဲလ်ရေးသူ ရွေးစရာများ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ဆော့ဖ်ဝဲရေးသူအတွက် ရွေးစရာများကို ဖွင့်ပါ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"အပလီကေးရှင်းတိုးတက်မှုအတွက် ရွေးချယ်မှုကိုသတ်မှတ်သည်"</string>
@@ -443,7 +441,7 @@
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaly (အနီ-အစိမ်း)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (အနီ-အစိမ်း)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (အပြာ-အဝါ)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင် အမှန်ပြင်ခြင်း"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင်ပြင်ခြင်း"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"အရောင် အမှန်ပြင်ခြင်းသည် အောက်ပါတို့အတွက် အသုံးဝင်နိုင်သည်-&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;အရောင်များကို ပိုမိုမှန်ကန်စွာ ကြည့်ရှုခြင်း&lt;/li&gt; &lt;li&gt;&amp;nbsp;အာရုံစိုက်နိုင်ရန် အရောင်များ ဖယ်ရှားခြင်း&lt;/li&gt; &lt;/ol&gt;"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
@@ -471,7 +469,7 @@
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"မကြာမီ စက်ပိတ်သွားနိုင်သည် (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုသည်"</string>
- <string name="power_charging_duration" msgid="6127154952524919719">"အားပြည့်ရန် <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
<string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ယခုလေးတင်"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ဤဖုန်း"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ဤတက်ဘလက်"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ဤဖုန်း"</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>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"ပြောင်းရန် အကောင့်အဆင့်ကိုမြှင့်ပါ"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ဤနေရာတွင် ဒေါင်းလုဒ်များ ဖွင့်မရပါ"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"ကြော်ငြာအပြီးတွင် ထပ်စမ်းကြည့်ပါ"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ဤနေရာတွင်ဖွင့်ရန် စက်ပစ္စည်းကိုနှိုးပါ"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ဒီမှာဖွင့်ရန် စက်ပစ္စည်းကိုနှိုးပါ"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"စက်ပစ္စည်းက ဖွင့်ခွင့်မပြုပါ"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"ဤမီဒီယာကို ဒီမှာဖွင့်၍မရပါ"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ချိတ်ဆက်ရာတွင် ပြဿနာရှိပါသည်။ စက်ကိုပိတ်ပြီး ပြန်ဖွင့်ပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index dc0d1bdd1ef1..b85dabb593f5 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-lyd"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Koblet til høreapparater"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Koblet til LE-lyd"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Koblet til medielyd"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Velg profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Personlig"</string>
<string name="category_work" msgid="4014193632325996115">"Jobb"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Utvikleralternativer"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Slå på utvikleralternativer"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Angi alternativer for apputvikling"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Nå nettopp"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Denne telefonen"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Dette nettbrettet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefonen"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke spille på denne enheten"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Oppgrader kontoen for å bytte"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan ikke spille av nedlastinger her"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prøv igjen etter annonsen"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Vekk enheten for å spille her"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten er ikke godkjent for avspilling"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Kan ikke spille dette medieinnholdet her"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten er ikke godkjent"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Kan ikke spille av dette her"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
<string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
@@ -577,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Bruker"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Begrenset profil"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Vil du legge til en ny bruker?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sin egen plass de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel wifi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for plassen sin.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sitt eget område de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel wifi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for sitt område.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Når du legger til en ny bruker, må hen konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Vil du gjøre denne brukeren til administrator?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorer har spesielle rettigheter som ikke andre brukere har. Administratorer kan administrere alle brukere, oppdatere og tilbakestille denne enheten, endre innstillinger, se alle installerte apper, gi administratorrettigheter til andre samt oppheve andres administratorrettigheter."</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 451f1985bd4b..f464f3135f49 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -23,7 +23,7 @@
<string-array name="wifi_status">
<item msgid="1596683495752107015"></item>
<item msgid="3288373008277313483">"स्क्यान गरिँदै..."</item>
- <item msgid="6050951078202663628">"जडान हुँदै..."</item>
+ <item msgid="6050951078202663628">"कनेक्ट गरिँदै छ..."</item>
<item msgid="8356618438494652335">"प्रमाणित गर्दै ..."</item>
<item msgid="2837871868181677206">"IP एड्रेस पत्ता लगाउँदै ..."</item>
<item msgid="4613015005934755724">"जडान गरिएको"</item>
@@ -37,7 +37,7 @@
<string-array name="wifi_status_with_ssid">
<item msgid="5969842512724979061"></item>
<item msgid="1818677602615822316">"स्क्यान गर्दै..."</item>
- <item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>सँग जडान हुँदै..."</item>
+ <item msgid="8339720953594087771">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>सँग कनेक्ट गरिँदै छ..."</item>
<item msgid="3028983857109369308">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>को साथ प्रमाणित गर्दै…"</item>
<item msgid="4287401332778341890">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>बाट IP एड्रेस प्राप्त गर्दै…"</item>
<item msgid="1043944043827424501">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> मा कनेक्ट भएको छ छ"</item>
@@ -59,9 +59,9 @@
<item msgid="6421717003037072581">"सधैँ HDCP जाँच प्रयोग गर्नुहोस्"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
- <item msgid="695678520785580527">"असक्षम पारिएको छ"</item>
- <item msgid="6336372935919715515">"फिल्टर सक्षम पारियो"</item>
- <item msgid="2779123106632690576">"सक्षम पारिएको छ"</item>
+ <item msgid="695678520785580527">"अफ गरिएको छ"</item>
+ <item msgid="6336372935919715515">"फिल्टर अफ पारियो"</item>
+ <item msgid="2779123106632690576">"अन गरिएको छ"</item>
</string-array>
<string-array name="bt_hci_snoop_log_filters_entries">
<item msgid="195768089203590086">"ACL हेडर मात्र छाड्नुहोस्"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d7cd9a69479f..b4749bf26554 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -84,7 +84,7 @@
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
<string name="bluetooth_disconnected" msgid="7739366554710388701">"विच्छेदन गरियो"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"जडान हटाइँदै ..."</string>
- <string name="bluetooth_connecting" msgid="5871702668260192755">"जडान हुँदै..."</string>
+ <string name="bluetooth_connecting" msgid="5871702668260192755">"कनेक्ट गरिँदै छ..."</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> सँग कनेक्ट भएको छ"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"कनेक्ट गरिँदै छ..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"जडान गरियो (फोनबाहेेक) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -99,7 +99,7 @@
<string name="bluetooth_battery_level" msgid="2893696778200201555">"ब्याट्रीको स्तर: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ब्याट्री, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ब्याट्री"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"सक्रिय"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"सक्रिय, बायाँ मात्र"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"बायाँ मात्र अन छ"</string>
<string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"सक्रिय, दायाँ मात्र"</string>
<string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"सक्रिय, बायाँ र दायाँ"</string>
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"मिडिया अडियो"</string>
@@ -111,7 +111,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"कन्ट्याक्ट र कल हिस्ट्री सेयर गर्न प्रयोग गरियोस्"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इन्टरनेट जडान साझेदारी गर्दै"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"टेक्स्ट म्यासेजहरू"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM पहुँच"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM एक्सेस"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD अडियो"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"श्रवण यन्त्रहरू"</string>
@@ -545,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"अहिले भर्खरै"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"यो फोन"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"यो ट्याब्लेट"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"यो फोन"</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>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड गरिएका सामग्री यसमा प्ले गर्न मिल्दैन"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"विज्ञापन सकिएपछि फेरि प्रयास गर्नुहोस्"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"यो मिडिया यहाँ प्ले गर्न डिभाइस सक्रिय गर्नुहोस्"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"यो डिभाइसलाई मिडिया प्ले गर्ने अनुमोदन दिइएको छैन"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"यो मिडिया यहाँ प्ले गर्न मिल्दैन"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"यो डिभाइसलाई मिडिया प्ले गर्ने अनुमति छैन"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"यो मिडिया यसमा प्ले गर्न मिल्दैन"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
<string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
@@ -574,7 +580,7 @@
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"तपाईं आफ्नो खाताबाट एपहरू र सामग्रीहरूको पहुँचलाई प्रतिबन्ध गर्न सक्नुहुन्छ"</string>
<string name="user_add_user_item_title" msgid="2394272381086965029">"प्रयोगकर्ता"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबन्धित प्रोफाइल"</string>
- <string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
+ <string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता हाल्ने हो?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।\n\nतपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।BREAK_0BREAK_1तपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।BREAK_2BREAK_3सबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तर पहुँचसम्बन्धी सेटिङ तथा सेवाहरू नयाँ प्रयोगकर्तामा नसर्न सक्छन्।"</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने ती प्रयोगकर्ताले आफ्नो स्पेस सेट गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"यी प्रयोगकर्तालाई एड्मिन बनाउने हो?"</string>
@@ -592,7 +598,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"प्रोफाइलको जानकारी"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"निषेधयुक्त प्रोफाइल बनाउनु अघि तपाईँको एप र व्यक्तिगत डेटा सुरक्षा गर्नाका लागि तपाईँले स्क्रिन लक सेटअप गर्नु पर्दछ ।"</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"लक सेट गर्नुहोस्"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"प्रयोगकर्ता बदलेर <xliff:g id="USER_NAME">%s</xliff:g> पार्नुहोस्"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"प्रयोगकर्ता बदलेर <xliff:g id="USER_NAME">%s</xliff:g> बनाउनुहोस्"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नयाँ प्रयोगकर्ता बनाइँदै छ…"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"नयाँ अतिथि बनाइँदै छ…"</string>
<string name="add_user_failed" msgid="4809887794313944872">"नयाँ प्रयोगकर्ता सिर्जना गर्न सकिएन"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 8e101d3e1671..02cdba4b12b8 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hoortoestellen"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met hoortoestellen"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Verbonden met LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbonden met audio van medium"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profiel kiezen"</string>
<string name="category_personal" msgid="6236798763159385225">"Persoonlijk"</string>
<string name="category_work" msgid="4014193632325996115">"Werk"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klonen"</string>
<string name="development_settings_title" msgid="140296922921597393">"Ontwikkelaarsopties"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Opties voor ontwikkelaars aanzetten"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Opties instellen voor appontwikkeling"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Zojuist"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Deze telefoon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Deze tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Deze telefoon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan niet afspelen op dit apparaat"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade het account om te schakelen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index b2e5fe130d6a..824119ec769f 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"ସଂଯୋଗ କରାଯାଉଛି…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"ସଂଯୁକ୍ତ ହେଲା<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"ପେୟାର୍‌ କରୁଛି…"</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"ପେୟାର କରୁଛି…"</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"ସଂଯୁକ୍ତ ହେଲା (ଫୋନ୍ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"ସଂଯୁକ୍ତ ହେଲା (ମିଡିଆ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"ସଂଯୁକ୍ତ ହେଲା (ଫୋନ୍ କିମ୍ବା ମେଡିଆ ନୁହେଁ)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ଅଡିଓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ଅଡିଓ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ଅଡିଓ"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ଶ୍ରବଣ ଯନ୍ତ୍ରକୁ ସଂଯୋଗ ହୋଇଛି"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ଅଡିଓ ସହ କନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ମିଡିଆ ଅଡିଓ ସହ ସଂଯୁକ୍ତ"</string>
@@ -175,7 +174,7 @@
<string name="launch_defaults_some" msgid="3631650616557252926">"କିଛି ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ମାନ ସେଟ୍‌ ହୋଇଛି"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"କୌଣସି ଡିଫଲ୍ଟ ସେଟ୍‍ ହୋଇନାହିଁ"</string>
<string name="tts_settings" msgid="8130616705989351312">"ଟେକ୍ସଟ୍-ଟୁ-ସ୍ପିଚ୍ ସେଟିଂସ"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"ଟେକ୍ସଟ୍‍-ଟୁ-ସ୍ପିଚ୍‍ ଆଉଟ୍‍ପୁଟ୍‌"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"ଟେକ୍ସଟ-ଟୁ-ସ୍ପିଚ ଆଉଟପୁଟ"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"ସ୍ପିଚ୍‌ ରେଟ୍"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"ଲେଖା ପଢ଼ିବାର ବେଗ"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"ପିଚ୍‌"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"ପ୍ରୋଫାଇଲ୍‌ ବାଛନ୍ତୁ"</string>
<string name="category_personal" msgid="6236798763159385225">"ବ୍ୟକ୍ତିଗତ"</string>
<string name="category_work" msgid="4014193632325996115">"ୱାର୍କ"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"କ୍ଲୋନ"</string>
<string name="development_settings_title" msgid="140296922921597393">"ଡେଭଲପରଙ୍କ ପାଇଁ ବିକଳ୍ପଗୁଡ଼ିକ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ଡେଭଲପର୍‌ ବିକଳ୍ପଗୁଡ଼ିକ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ଆପ୍‌ର ବିକାଶ ପାଇଁ ବିକଳ୍ପମାନ ସେଟ୍‌ କରନ୍ତୁ"</string>
@@ -272,10 +270,10 @@
<string name="debug_networking_category" msgid="6829757985772659599">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string>
- <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"ୱାଇ-ଫାଇ ଅଣ-ଅବିରତ MAC ରେଣ୍ଡମାଇଜେସନ୍"</string>
- <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
- <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ ନିୟନ୍ତ୍ରଣ"</string>
+ <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"ୱାଇ-ଫାଇ ଅଣ-ଅବିରତ MAC ରେଣ୍ଡମାଇଜେସନ"</string>
+ <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
+ <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ବ୍ଲୁଟୂଥ ଡିଭାଇସଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖାନ୍ତୁ"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"ପୂର୍ଣ୍ଣ ଭଲ୍ୟୁମ୍‌ ଅକ୍ଷମ କରନ୍ତୁ"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"ଗାବେଲ୍‌ଡୋର୍ସ ସକ୍ରିୟ କରନ୍ତୁ"</string>
@@ -304,8 +302,8 @@
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"ୱେୟାରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍‌ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ଯେତେବେଳେ ଏହି ମୋଡ୍ ସକ୍ଷମ କରାଯାଏ, ପ୍ରତ୍ୟେକ ଥର MAC ରେଣ୍ଡୋମାଇଜେସନ୍ ସକ୍ଷମ ଥିବା କୌଣସି ନେଟୱାର୍କ ସହ ଏହି ଡିଭାଇସ୍ ସଂଯୋଗ ହେଲେ ଏହାର MAC ଠିକଣା ବଦଳିପାରେ।"</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବେଟେରୀ ଖର୍ଚ୍ଚକୁ କମ ଏବଂ ନେଟୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତାକୁ ଉନ୍ନତ କରିଥାଏ"</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ଯେତେବେଳେ ଏହି ମୋଡକୁ ସକ୍ଷମ କରାଯାଏ, ପ୍ରତ୍ୟେକ ଥର MAC ରେଣ୍ଡମାଇଜେସନ ସକ୍ଷମ ଥିବା କୌଣସି ନେଟୱାର୍କ ସହ ଏହି ଡିଭାଇସ ସଂଯୋଗ ହେଲେ ଏହାର MAC ଠିକଣା ବଦଳିପାରେ।"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"ମପାଯାଉଥିବା"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"ମପାଯାଉନଥିବା"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"ଲଗର୍‌ ବଫର୍‌ ସାଇଜ୍"</string>
@@ -319,8 +317,8 @@
<string name="allow_mock_location" msgid="2102650981552527884">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"ବିଶେଷତା ଯାଞ୍ଚ ଭ୍ୟୁକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ୍‌ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟ୍‌ୱର୍କ ସ୍ୱିଚିଙ୍ଗ ପାଇଁ)।"</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର୍‌ ଆକ୍ସିଲିରେସନ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟୱାର୍କ ସ୍ୱିଚିଂ ପାଇଁ)।"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ତେବେ ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB ଡିବଗିଂ କେବଳ ଡେଭଲପମେଣ୍ଟ ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍‌ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପସ୍‌ ସଂସ୍ଥାପନ କରିବାକୁ, ଏବଂ ଲଗ୍‌ ଡାଟା ପଢିବାକୁ ଏହା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ଦେବେ?"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ଏହିକ୍ଷଣି"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ଏହି ଫୋନ"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ଏହି ଟାବଲେଟ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ଏହି ଫୋନ୍"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ଏହି ଡିଭାଇସରେ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ସ୍ୱିଚ କରିବା ପାଇଁ ଆକାଉଣ୍ଟକୁ ଅପଗ୍ରେଡ କରନ୍ତୁ"</string>
@@ -580,7 +584,7 @@
<string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ୟୁଜରଙ୍କୁ ଯୋଗ କରି ଆପଣ ଏହି ଡିଭାଇସକୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର କରିପାରିବେ। ପ୍ରତ୍ୟେକ ୟୁଜରଙ୍କ ନିଜର ସ୍ପେସ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ, ୱାଲପେପର ଓ ଏପରି ଅନେକ କିଛି ସହିତ କଷ୍ଟମାଇଜ କରିପାରିବେ। ୟୁଜର ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ ସେଟିଂସକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଜଣେ ନୂଆ ୟୁଜରଙ୍କୁ ଯୋଗ କରିବେ, ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ନିଜର ସ୍ପେସକୁ ସେଟ‌ଅପ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ୟୁଜରଙ୍କ ପାଇଁ ଯେ କୌଣସି ୟୁଜର ଆପକୁ ଅପଡେଟ କରିପାରିବେ। ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ ଏବଂ ସେବାଗୁଡ଼ିକ ନୂଆ ୟୁଜରଙ୍କୁ ସ୍ଥାନାନ୍ତର ହୋ‌ଇନପାରେ।"</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"ଆପଣ ଜଣେ ନୂଆ ୟୁଜରଙ୍କୁ ଯୋଗ କରିବା ବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ତାଙ୍କ ସ୍ପେସ ସେଟ ଅପ କରିବାକୁ ପଡ଼ିବ।\n\nଅନ୍ୟ ସମସ୍ତ ୟୁଜରଙ୍କ ପାଇଁ ଆପ୍ସକୁ ଯେ କୌଣସି ୟୁଜର ଅପଡେଟ କରିପାରିବେ।"</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"ଏହି ୟୁଜରଙ୍କୁ ଜଣେ ଆଡମିନ କରିବେ?"</string>
- <string name="user_grant_admin_message" msgid="1673791931033486709">"ଆଡମିନମାନଙ୍କର ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକ ଥାଏ ଯାହା ଅନ୍ୟ ୟୁଜରମାନଙ୍କର ନଥାଏ। ଜଣେ ଆଡମିନ ସମସ୍ତ ୟୁଜରଙ୍କୁ ପରିଚାଳନା କରିପାରିବେ, ଏହି ଡିଭାଇସକୁ ଅପଡେଟ କିମ୍ବା ରିସେଟ କରିପାରିବେ, ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିପାରିବେ, ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖିପାରିବେ ଏବଂ ଅନ୍ୟମାନଙ୍କ ପାଇଁ ଆଡମିନ ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇପାରିବେ କିମ୍ବା ପ୍ରତ୍ୟାହାର କରିପାରିବେ।"</string>
+ <string name="user_grant_admin_message" msgid="1673791931033486709">"ଆଡମିନମାନଙ୍କର ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକ ଥାଏ ଯାହା ଅନ୍ୟ ୟୁଜରମାନଙ୍କର ନଥାଏ। ଜଣେ ଆଡମିନ ସମସ୍ତ ୟୁଜରଙ୍କୁ ପରିଚାଳନା କରିପାରିବେ, ଏହି ଡିଭାଇସକୁ ଅପଡେଟ କିମ୍ବା ରିସେଟ କରିପାରିବେ, ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିପାରିବେ, ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖିପାରିବେ ଏବଂ ଅନ୍ୟମାନଙ୍କ ପାଇଁ ଆଡମିନଙ୍କ ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇପାରିବେ କିମ୍ବା ପ୍ରତ୍ୟାହାର କରିପାରିବେ।"</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"ଆଡମିନ କରନ୍ତୁ"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ଉପଯୋଗକର୍ତ୍ତା ସେଟଅପ କରିବେ?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍‌ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ୍‌ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
@@ -594,7 +598,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"ପ୍ରୋଫାଇଲ୍ ସୂଚନା"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"ପ୍ରତିବନ୍ଧିତ ପ୍ରୋଫାଇଲ୍‌ ତିଆରି କରିବାବେଳେ, ନିଜ ଆପ୍‌ ଓ ବ୍ୟକ୍ତିଗତ ତଥ୍ୟର ସୁରକ୍ଷା ପାଇଁ ଏକ ସ୍କ୍ରୀନ୍‌ ଲକ୍‌ ସେଟ୍‌ କରନ୍ତୁ।"</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"ଲକ୍‌ ସେଟ୍‌ କରନ୍ତୁ"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>କୁ ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>କୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ନୂଆ ୟୁଜର ତିଆରି କରାଯାଉଛି…"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"ନୂଆ ଅତିଥି ତିଆରି କରାଯାଉଛି…"</string>
<string name="add_user_failed" msgid="4809887794313944872">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବାକୁ ବିଫଳ ହେଲା"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 533788abbfcd..4225e02996e4 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -200,7 +200,7 @@
</string-array>
<string-array name="select_logpersist_summaries">
<item msgid="97587758561106269">"ਬੰਦ"</item>
- <item msgid="7126170197336963369">"ਸਭ ਲੌਗ ਬਫ਼ਰ"</item>
+ <item msgid="7126170197336963369">"ਸਾਰੇ ਲੌਗ ਬਫ਼ਰ"</item>
<item msgid="7167543126036181392">"ਸਭ ਪਰ ਰੇਡੀਓ ਲੌਗ ਬਫ਼ਰ"</item>
<item msgid="5135340178556563979">"ਸਿਰਫ਼ ਕਰਨਲ ਲੌਗ ਬਫ਼ਰ"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index e93737f142ca..482315fd785b 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ਆਡੀਓ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ਆਡੀਓ"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ਸੁਣਨ ਦੇ ਸਾਧਨਾਂ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ਆਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ਮੀਡੀਆ ਆਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
<string name="category_personal" msgid="6236798763159385225">"ਨਿੱਜੀ"</string>
<string name="category_work" msgid="4014193632325996115">"ਕੰਮ ਸੰਬੰਧੀ"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ਕਲੋਨ ਕਰੋ"</string>
<string name="development_settings_title" msgid="140296922921597393">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ਐਪ ਵਿਕਾਸ ਲਈ ਚੋਣਾਂ ਸੈੱਟ ਕਰੋ"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ਹੁਣੇ ਹੀ"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ਇਹ ਫ਼ੋਨ"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ਇਹ ਟੈਬਲੈੱਟ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ਇਹ ਫ਼ੋਨ"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ਸਵਿੱਚ ਕਰਨ ਲਈ ਖਾਤੇ ਨੂੰ ਅੱਪਗ੍ਰੇਡ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index f665850af430..031cd9c04910 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -257,7 +257,7 @@
<item msgid="1212561935004167943">"Wyróżnij testowane polecenia rysowania na zielono"</item>
</string-array>
<string-array name="track_frame_time_entries">
- <item msgid="634406443901014984">"Wyłączone"</item>
+ <item msgid="634406443901014984">"Wyłączono"</item>
<item msgid="1288760936356000927">"Na ekranie w postaci pasków"</item>
<item msgid="5023908510820531131">"W: <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index dbcc7440e22c..742574450a6f 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Dźwięk HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Dźwięk HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparaty słuchowe"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Połączono z aparatami słuchowymi"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Połączono z LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Połączono z funkcją audio multimediów"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anuluj"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Sparowanie powoduje przyznanie dostępu do historii połączeń i Twoich kontaktów w trakcie połączenia."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nie udało się sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nie udało się sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ze względu na błędny kod PIN lub klucz."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nieudane parowanie z: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Błędny kod PIN lub klucz dostępu."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nie można skomunikować się z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Powiązanie odrzucone przez urządzenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Komputer"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Osobiste"</string>
<string name="category_work" msgid="4014193632325996115">"Służbowe"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opcje programisty"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje programisty"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Przed chwilą"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ten telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ten tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ten telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nie można odtworzyć na tym urządzeniu"</string>
- <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uaktualnij konto, aby przełączyć"</string>
+ <string name="media_output_status_require_premium" msgid="8411255800047014822">"Aby przełączyć, potrzebujesz konta premium"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tutaj nie można odtworzyć pobranych plików"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Spróbuj ponownie po reklamie"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wybudź urządzenie, aby odtworzyć tutaj"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wybudź, aby tu odtworzyć"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Urządzenie nie ma uprawnień do odtwarzania"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Nie można odtworzyć tego pliku multimedialnego"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
@@ -577,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Użytkownik"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil ograniczony"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Dodać nowego użytkownika?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Z tego urządzenia możesz korzystać wraz z innymi osobami, dodając na nim konta użytkowników. Każdy użytkownik ma własne miejsce na swoje aplikacje, tapety i inne dane. Może też zmieniać ustawienia, które wpływają na wszystkich użytkowników urządzenia (np. Wi‑Fi).\n\nGdy dodasz nowego użytkownika, musi on skonfigurować swoje miejsce na dane.\n\nKażdy użytkownik może aktualizować aplikacje w imieniu wszystkich pozostałych użytkowników. Ułatwienia dostępu i usługi mogą nie zostać przeniesione na konto nowego użytkownika."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Na tym urządzeniu możesz dodać konta użytkowników i dzięki temu korzystać z niego wraz z innymi osobami. Każdy użytkownik ma własne miejsce na swoje aplikacje, tapety i inne dane. Może też zmieniać ustawienia (np. Wi‑Fi), które wpływają na wszystkich użytkowników urządzenia.\n\nGdy dodasz nowego użytkownika, musi on skonfigurować swoje miejsce na dane.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich pozostałych użytkowników. Ułatwienia dostępu i usługi mogą nie zostać przeniesione na konto nowego użytkownika."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Gdy dodasz nowego użytkownika, musi on skonfigurować swoją przestrzeń.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Przyznać temu użytkownikowi uprawnienia administratora?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorzy mają specjalne uprawnienia, którymi nie dysponują pozostali użytkownicy. Administrator może zarządzać wszystkimi użytkownikami, aktualizować i resetować urządzenie, modyfikować ustawienia, wyświetlać wszystkie zainstalowane aplikacje oraz przyznawać uprawnienia administratora innym użytkownikom i je wycofywać."</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 13209e60db0b..e8a39664034b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"O pareamento dá acesso a seus contatos e ao histórico de ligações quando estiver conectado."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou senha incorretos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telefone"</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">"Faça upgrade da conta para trocar"</string>
@@ -575,9 +581,9 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Usuário"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restrito"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Adicionar novo usuário?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Você pode compartilhar este dispositivo com outras pessoas, adicionando usuários. Cada usuário tem o próprio espaço, que pode ser personalizado com apps, planos de fundo, etc. Os usuários também podem ajustar as configurações do dispositivo, como o Wi‑Fi, que afetam a todos.\n\nQuando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para todos os outros. Serviços e configurações de acessibilidade podem não ser transferidos para novos usuários."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Você pode compartilhar este dispositivo com outras pessoas, adicionando usuários. Cada um tem o próprio espaço de trabalho, que pode ser personalizado com apps, planos de fundo, etc. Também é possível ajustar as configurações do dispositivo, como o Wi‑Fi, que afetam a todos.\n\nQuando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para todos os outros. Serviços e configurações de acessibilidade podem não ser transferidos para novos usuários."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
- <string name="user_grant_admin_title" msgid="5157031020083343984">"Transformar esse usuário um administrador?"</string>
+ <string name="user_grant_admin_title" msgid="5157031020083343984">"Tornar esse usuário um administrador?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administradores têm privilégios especiais que outros usuários não têm. Um administrador pode gerenciar todos os usuários, atualizar ou redefinir este dispositivo, modificar configurações, conferir todos os apps instalados e conceder ou revogar privilégios de administrador para outras pessoas."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Transformar o usuário em administrador"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurar o usuário agora?"</string>
@@ -611,7 +617,7 @@
<string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
- <string name="grant_admin" msgid="4323199171790522574">"Sim, transformar esse usuário em administrador"</string>
+ <string name="grant_admin" msgid="4323199171790522574">"Sim, tornar esse usuário um administrador"</string>
<string name="not_grant_admin" msgid="3557849576157702485">"Não, não transformar o usuário em administrador"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvar a atividade do visitante?"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 1f146cee871e..8b9d33af0cd3 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ligado a aparelhos auditivos"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ligado a LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ligado ao áudio de multimédia"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A sincronização concede acesso aos seus contactos e ao histórico de chamadas quando tem uma ligação estabelecida."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> devido a PIN ou token de acesso incorreto."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou chave de acesso errado."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Escolher perfil"</string>
<string name="category_personal" msgid="6236798763159385225">"Pessoal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabalho"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Opções de programador"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Ativar as opções de programador"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Definir opções de desenvolvimento da aplicação"</string>
@@ -518,7 +516,7 @@
<string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Não registado"</string>
<string name="status_unavailable" msgid="5279036186589861608">"Indisponível"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"O MAC é aleatório."</string>
- <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 dispositivo ligados}=1{1 dispositivo ligado}other{# dispositivos ligados}}"</string>
+ <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 dispositivo ligado}=1{1 dispositivo ligado}other{# dispositivos ligados}}"</string>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mais tempo."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tempo."</string>
<string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telemóvel"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</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>
@@ -578,7 +582,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restrito"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Adicionar novo utilizador?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Pode partilhar este dispositivo com outras pessoas ao criar utilizadores adicionais. Cada utilizador possui o seu próprio espaço, que pode ser personalizado com apps, imagens de fundo, etc. Os utilizadores também podem ajustar as definições do dispositivo, como o Wi‑Fi, que afetam os restantes utilizadores.\n\nAo adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores. Os serviços e as definições de acessibilidade podem não ser transferidos para o novo utilizador."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Definir este utilizador como um administrador?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Os administradores têm privilégios especiais que outros utilizadores não têm. Um administrador pode gerir todos os utilizadores, atualizar ou repor este dispositivo, modificar definições, ver todas as apps instaladas e revogar ou conceder privilégios de administrador a outras pessoas."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Definir como administrador"</string>
@@ -590,7 +594,7 @@
<string name="user_add_user_type_title" msgid="551279664052914497">"Adicionar"</string>
<string name="user_new_user_name" msgid="60979820612818840">"Novo utilizador"</string>
<string name="user_new_profile_name" msgid="2405500423304678841">"Novo perfil"</string>
- <string name="user_info_settings_title" msgid="6351390762733279907">"Info. utilizador"</string>
+ <string name="user_info_settings_title" msgid="6351390762733279907">"Dados do utilizador"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"Informação do perfil"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Antes de poder criar um perfil restrito, tem de configurar um bloqueio de ecrã para proteger as suas aplicações e dados pessoais."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Definir bloqueio"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 13209e60db0b..e8a39664034b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"O pareamento dá acesso a seus contatos e ao histórico de ligações quando estiver conectado."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou senha incorretos."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telefone"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telefone"</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">"Faça upgrade da conta para trocar"</string>
@@ -575,9 +581,9 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Usuário"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restrito"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Adicionar novo usuário?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Você pode compartilhar este dispositivo com outras pessoas, adicionando usuários. Cada usuário tem o próprio espaço, que pode ser personalizado com apps, planos de fundo, etc. Os usuários também podem ajustar as configurações do dispositivo, como o Wi‑Fi, que afetam a todos.\n\nQuando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para todos os outros. Serviços e configurações de acessibilidade podem não ser transferidos para novos usuários."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Você pode compartilhar este dispositivo com outras pessoas, adicionando usuários. Cada um tem o próprio espaço de trabalho, que pode ser personalizado com apps, planos de fundo, etc. Também é possível ajustar as configurações do dispositivo, como o Wi‑Fi, que afetam a todos.\n\nQuando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para todos os outros. Serviços e configurações de acessibilidade podem não ser transferidos para novos usuários."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
- <string name="user_grant_admin_title" msgid="5157031020083343984">"Transformar esse usuário um administrador?"</string>
+ <string name="user_grant_admin_title" msgid="5157031020083343984">"Tornar esse usuário um administrador?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administradores têm privilégios especiais que outros usuários não têm. Um administrador pode gerenciar todos os usuários, atualizar ou redefinir este dispositivo, modificar configurações, conferir todos os apps instalados e conceder ou revogar privilégios de administrador para outras pessoas."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Transformar o usuário em administrador"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurar o usuário agora?"</string>
@@ -611,7 +617,7 @@
<string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
<string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
<string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
- <string name="grant_admin" msgid="4323199171790522574">"Sim, transformar esse usuário em administrador"</string>
+ <string name="grant_admin" msgid="4323199171790522574">"Sim, tornar esse usuário um administrador"</string>
<string name="not_grant_admin" msgid="3557849576157702485">"Não, não transformar o usuário em administrador"</string>
<string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
<string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvar a atividade do visitante?"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index edad3bd9ed5f..244dc6fed7d2 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Chiar acum"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Acest telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Această tabletă"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Acest telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nu se poate reda pe acest dispozitiv"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Fă upgrade contului pentru a comuta"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index d40eb69e95d3..321fe6faa886 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -59,7 +59,7 @@
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"Возможно, вы указали неверный пароль. Повторите попытку."</string>
<string name="wifi_not_in_range" msgid="1541760821805777772">"Недоступна"</string>
<string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Подключение не будет выполняться автоматически"</string>
- <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к Интернету"</string>
+ <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к интернету"</string>
<string name="saved_network" msgid="7143698034077223645">"Сохранено: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматически подключено к %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматически подключено через автора рейтинга сетей"</string>
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Отключение..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Подключение..."</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Подключено<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"Устанавливается соединение..."</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"Подключение..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Подключено (кроме звонков)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Подключено (кроме аудио)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Подключено (кроме звонков и аудио)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD Audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слуховые аппараты"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Слуховой аппарат подключен"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Подключено к LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Подключено к мультимедийному аудиоустройству"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Отмена"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Установление соединения обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Устройство \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" не подключено: неверный PIN-код или пароль."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"\"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" не подключается: неверный PIN-код или пароль."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает подключение."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компьютер"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Выбор профиля"</string>
<string name="category_personal" msgid="6236798763159385225">"Личный профиль"</string>
<string name="category_work" msgid="4014193632325996115">"Рабочий профиль"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Для разработчиков"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Включить параметры для разработчиков"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Настройка параметров для разработчиков"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Только что"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Этот смартфон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Этот планшет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Этот смартфон"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Невозможно воспроизвести на этом устройстве."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Для переключения требуется премиум-аккаунт"</string>
@@ -580,7 +584,7 @@
<string name="user_add_user_message_long" msgid="1527434966294733380">"Если этим устройством пользуются сразу несколько человек, для каждого из них можно создать профиль – отдельное пространство с выбранными приложениями, обоями и т. д. Новый пользователь настраивает его сам.\n\nИз профиля можно поменять и общие настройки устройства, например сеть Wi-Fi.\n\nОбновлять общие приложения могут все, однако специальные возможности настраиваются индивидуально."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"После создания профиля его потребуется настроить.\n\nЛюбой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Назначить этого пользователя администратором?"</string>
- <string name="user_grant_admin_message" msgid="1673791931033486709">"У администраторов права шире, чем у других пользователей. Администратор может управлять всеми пользователями, обновлять и сбрасывать это устройство, менять настройки, просматривать установленные приложения, а также предоставлять и отзывать права администратора."</string>
+ <string name="user_grant_admin_message" msgid="1673791931033486709">"У администраторов права шире, чем у других пользователей. Администратор может управлять аккаунтами всех пользователей, обновлять ПО на устройстве, менять и сбрасывать его настройки, просматривать установленные приложения, а также предоставлять и отзывать права администратора."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Назначить администратором"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"Настроить профиль?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"Вам потребуется передать устройство пользователю, чтобы он мог настроить свой профиль."</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 4289012cbf0e..400a6e5c44da 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ශ්‍රව්‍යය: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ශ්‍රව්‍යය"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ශ්‍රවණාධාරක"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ශ්‍රව්‍ය"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ශ්‍රවණාධාරක වෙත සම්බන්ධ කළා"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ශ්‍රව්‍ය වෙත සම්බන්ධ විය"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"මාධ්‍ය ශ්‍රව්‍යට සම්බන්ධ විය"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"පැතිකඩ තෝරන්න"</string>
<string name="category_personal" msgid="6236798763159385225">"පෞද්ගලික"</string>
<string name="category_work" msgid="4014193632325996115">"කාර්යාලය"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"ක්ලෝන කරන්න"</string>
<string name="development_settings_title" msgid="140296922921597393">"වර්ධක විකල්ප"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"සංවර්ධක විකල්ප සබල කිරීම"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"යෙදුම් සංවර්ධනයට විකල්ප සකසන්න"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"මේ දැන්"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"මෙම දුරකථනය"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"මෙම ටැබ්ලටය"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"මෙම දුරකථනය"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"මෙම උපාංගය මත ධාවනය කළ නොහැක"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"මාරු වීමට ගිණුම උත්ශ්‍රේණි කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 2b6258760029..9806d5957742 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -107,7 +107,7 @@
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prístup na internet"</string>
- <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Zdieľanie kontaktov a histórie hovorov"</string>
+ <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Zdieľať kontakty a históriu hovorov"</string>
<string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Používané pri zdieľaní kontaktov a histórie hovorov"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Zdieľanie pripojenia na Internet"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové správy"</string>
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Zrušiť"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Párovaním udelíte zariadeniam po pripojení prístup k svojim kontaktom a histórii hovorov."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nepodarilo sa spárovať so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> sa nespárovalo pre nesprávny kód PIN alebo prístupový kľúč."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nespárované so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: nesprávny PIN či prístupový kľúč."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nie je možné komunikovať."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Párovanie odmietnuté zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Počítač"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Teraz"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tento telefón"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tento tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefón"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"V tomto zariadení sa nedá prehrávať obsah"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Inovujte účet a prejdite naň"</string>
@@ -552,7 +558,7 @@
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Skúste to znova po reklame"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Ak chcete prehrávať obsah tu, prebuďte zariadenie"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Prehrávanie v tomto zariadení nie je schválené"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Tu sa toto médium nedá prehrať"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Médium sa tu nedá prehrať"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio zariadenie s káblom"</string>
<string name="help_label" msgid="3528360748637781274">"Pomocník a spätná väzba"</string>
@@ -575,8 +581,8 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Používateľ"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Obmedzený profil"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Pridať nového používateľa?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Vytvorením ďalších používateľov môžete toto zariadenie zdieľať s inými ľuďmi. Každý používateľ má svoje prostredie, ktoré si môže prispôsobiť vlastnými aplikáciami, tapetou atď. Používatelia tiež môžu upraviť nastavenia zariadenia (napr. Wi-Fi), ktoré ovplyvnia všetkých používateľov.\n\nKeď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nAkýkoľvek používateľ môže aktualizovať aplikácie všetkých používateľov. Nastavenia dostupnosti a služby sa nemusia preniesť novému používateľovi."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nAkýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Vytvorením ďalších používateľov môžete toto zariadenie zdieľať s inými ľuďmi. Každý používateľ má svoje prostredie, ktoré si môže prispôsobiť vlastnými aplikáciami, tapetou atď. Používatelia tiež môžu upraviť nastavenia zariadenia (napr. Wi-Fi), ktoré ovplyvnia všetkých používateľov.\n\nKeď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nKaždý používateľ môže aktualizovať aplikácie všetkých používateľov. Nastavenia dostupnosti a služby sa nemusia preniesť novému používateľovi."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nKaždý používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Chcete tohto používateľa nastaviť ako správcu?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Správcovia majú oproti iným používateľom špeciálne oprávnenia. Správca môže ovládať všetkých používateľov, aktualizovať alebo resetovať toto zariadenie, upravovať nastavenia, prezerať všetky nainštalované aplikácie a udeľovať či odoberať správcovské oprávnenia iným používateľom."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Nastaviť ako správcu"</string>
@@ -671,7 +677,7 @@
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Vyberte rozloženie klávesnice"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predvolené"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"Zapínanie obrazovky"</string>
- <string name="allow_turn_screen_on" msgid="6194845766392742639">"Povolenie zapínania obrazovky"</string>
+ <string name="allow_turn_screen_on" msgid="6194845766392742639">"Povoliť zapínanie obrazovky"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Povoľte aplikácii zapínať obrazovku. Ak to urobíte, aplikácia bude môcť kedykoľvek zapínať obrazovku, a to aj vtedy, keď to nebudete mať v úmysle."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 76fc8e3d7589..86cb46d572c6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Zvok visoke kakovosti"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni pripomočki"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE zvok"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezava s slušnimi pripomočki je vzpostavljena"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano s profilom LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezan s profilom za predstavnostni zvok"</string>
@@ -215,9 +214,8 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Izbira profila"</string>
<string name="category_personal" msgid="6236798763159385225">"Osebno"</string>
- <string name="category_work" msgid="4014193632325996115">"Služba"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_work" msgid="4014193632325996115">"Delo"</string>
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Možnosti za razvijalce"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Omogočanje možnosti za razvijalce"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Nastavi možnosti za razvoj aplikacij"</string>
@@ -547,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Pravkar"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ta telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ta tablični računalnik"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ta telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ni mogoče predvajati v tej napravi."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Za preklop je potrebna nadgradnja računa"</string>
- <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tukaj ni mogoče predvajati prenosov"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Prenosov tu ni mogoče predvajati"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Poskusite znova po oglasu"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Zbudite napravo, če želite predvajati tukaj."</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Zbudite napravo za predvajanje tu"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Naprava ni odobrena za predvajanje."</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Te predstavnosti ni mogoče predvajati tukaj."</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
@@ -594,7 +598,7 @@
<string name="profile_info_settings_title" msgid="105699672534365099">"Podatki za profil"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"Preden lahko ustvarite profil z omejitvami, morate nastaviti zaklepanje zaslona, da zaščitite aplikacije in osebne podatke."</string>
<string name="user_set_lock_button" msgid="1427128184982594856">"Nastavi zaklepanje"</string>
- <string name="user_switch_to_user" msgid="6975428297154968543">"Preklopi na račun <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+ <string name="user_switch_to_user" msgid="6975428297154968543">"Preklopi na uporabnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ustvarjanje novega uporabnika …"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Ustvarjanje novega gosta …"</string>
<string name="add_user_failed" msgid="4809887794313944872">"Ustvarjanje novega uporabnika ni uspelo."</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 7d43c0a1828e..c2cecebb142a 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -520,7 +520,7 @@
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Më shumë kohë."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Më pak kohë."</string>
<string name="cancel" msgid="5665114069455378395">"Anulo"</string>
- <string name="next" msgid="2699398661093607009">"Tjetri"</string>
+ <string name="next" msgid="2699398661093607009">"Para"</string>
<string name="back" msgid="5554327870352703710">"Prapa"</string>
<string name="save" msgid="3745809743277153149">"Ruaj"</string>
<string name="okay" msgid="949938843324579502">"Në rregull"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Pikërisht tani"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ky telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ky tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ky telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nuk mund të luhet në këtë pajisje"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Përmirëso llogarinë për të ndryshuar"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index cfad75e31b94..041b515a18ce 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -60,7 +60,7 @@
<string name="wifi_not_in_range" msgid="1541760821805777772">"Није у опсегу"</string>
<string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
<string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
- <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="saved_network" msgid="7143698034077223645">"Чува <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
<string name="connected_via_app" msgid="3532267661404276584">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -141,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Упаривање омогућава приступ контактима и историји позива након повезивања."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Рачунар"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Управо"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Овај телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Овај таблет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Овај телефон"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не можете да пустите на овом уређају"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надоградите налог ради пребацивања"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 8d4b9207e8f2..453f2cf96946 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ljud"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörapparater"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ansluten till hörapparater"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ansluten till LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ansluten till medialjud"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Om du kopplar enheten får du tillgång till dina kontakter och din samtalshistorik när du är ansluten."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grund av en felaktig PIN-kod eller nyckel."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Parkoppling med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> misslyckades på grund av fel PIN-kod eller nyckel."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Det går inte att kommunicera med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Parkoppling avvisad av <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Dator"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Välj profil"</string>
<string name="category_personal" msgid="6236798763159385225">"Privat"</string>
<string name="category_work" msgid="4014193632325996115">"Jobb"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Utvecklaralternativ"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Aktivera utvecklaralternativ"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Ange alternativ för apputveckling"</string>
@@ -547,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Nyss"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Den här telefonen"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Den här surfplattan"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Den här telefonen"</string>
- <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Det går inte att spela upp denna enhet"</string>
+ <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan inte spelas på denna enhet"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppgradera kontot för att byta"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Det går inte att spela upp nedladdningar här"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Försök igen efter annonsen"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Väck enheten för att spela upp här"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten har inte godkänts för uppspelning"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten är inte godkänd"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Det går inte att spela upp detta här"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
@@ -578,7 +582,7 @@
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Begränsad profil"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Lägga till ny användare?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dela enheten med andra om du skapar flera användare. Alla användare får sitt eget utrymme som de kan anpassa som de vill med appar, bakgrund och så vidare. Användarna kan även ändra enhetsinställningar som påverkar alla, till exempel wifi.\n\nNär du lägger till en ny användare måste han eller hon konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning. Tillgänglighetsinställningar och tjänster kanske inte överförs till den nya användaren."</string>
- <string name="user_add_user_message_short" msgid="3295959985795716166">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
+ <string name="user_add_user_message_short" msgid="3295959985795716166">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användare."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Vill du göra denna användare till administratör?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Administratörer har särskilda behörigheter som andra användare inte har. En administratör kan hantera alla användare, uppdatera eller återställa den här enheten, ändra inställningar, se alla installerade appar och bevilja eller återkalla administratörsbehörigheter för andra."</string>
<string name="user_grant_admin_button" msgid="5441486731331725756">"Gör till administratör"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index e104582a1879..d6fdc1ebbdaf 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -214,7 +214,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Chagua wasifu"</string>
<string name="category_personal" msgid="6236798763159385225">"Binafsi"</string>
- <string name="category_work" msgid="4014193632325996115">"Ya Kazini"</string>
+ <string name="category_work" msgid="4014193632325996115">"Kazini"</string>
<string name="category_clone" msgid="1554511758987195974">"Kloni"</string>
<string name="development_settings_title" msgid="140296922921597393">"Chaguo za wasanidi"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Washa chaguo za wasanidi programu"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Sasa hivi"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Simu hii"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Kompyuta kibao hii"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Simu hii"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Huwezi kucheza maudhui kwenye kifaa hiki"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Pata toleo jipya la akaunti ili ubadilishe"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 0dc5117099a8..fa39a7179ea4 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ஆடியோ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ஆடியோ"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"செவித்துணை கருவிகள்"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ஆடியோ"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"செவித்துணை கருவிகளுடன் இணைக்கப்பட்டது"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ஆடியோவுடன் இணைக்கப்பட்டுள்ளது"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"மீடியா ஆடியோவுடன் இணைக்கப்பட்டது"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"சுயவிவரத்தைத் தேர்வு செய்க"</string>
<string name="category_personal" msgid="6236798763159385225">"தனிப்பட்டவை"</string>
<string name="category_work" msgid="4014193632325996115">"பணியிடம்"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"குளோன்"</string>
<string name="development_settings_title" msgid="140296922921597393">"டெவெலப்பர் விருப்பங்கள்"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"டெவெலப்பர் விருப்பங்களை இயக்கு"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ஆப்ஸின் மேம்பாட்டிற்காக விருப்பங்களை அமை"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"சற்றுமுன்"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"இந்த மொபைல்"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"இந்த டேப்லெட்"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"இந்த மொபைல்"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"இந்தச் சாதனத்தில் பிளே செய்ய முடியவில்லை"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"மாற்ற, கணக்கை மேம்படுத்துங்கள்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index fcdad545c598..e8336f00605f 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -214,7 +214,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
<string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
- <string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
+ <string name="category_work" msgid="4014193632325996115">"వర్క్"</string>
<string name="category_clone" msgid="1554511758987195974">"క్లోన్ చేయండి"</string>
<string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఆప్షన్‌లు"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
@@ -545,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ఇప్పుడే"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"ఈ ఫోన్"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"ఈ టాబ్లెట్"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ఈ ఫోన్"</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>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"యాడ్ తర్వాత మళ్లీ ట్రై చేయండి"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"ఇక్కడ ప్లే చేయడానికి పరికరాన్ని మేల్కొలపండి"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ప్లే చేయడానికి పరికరానికి అధికారం ఇవ్వలేదు"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"ఇక్కడ ఈ మీడియాను ప్లే చేయడం సాధ్యపడదు"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"ప్లే చేయడానికి పరికరానికి అనుమతి లేదు"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"ఈ మీడియాను ఇక్కడ ప్లే చేయడం సాధ్యపడదు."</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
<string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
@@ -575,11 +581,11 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"యూజర్"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"పరిమితం చేయబడిన ప్రొఫైల్"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"కొత్త యూజర్‌ను జోడించాలా?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్‌లను క్రియేట్ చేయడం ద్వారా మీరు ఈ పరికరాన్ని ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్‌కు‌ వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్‌లు, వాల్‌పేపర్ మొదలైనవాటితో అనుకూలంగా మార్చవచ్చు. యూజర్‌లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్‌లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్‌ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగిలిన యూజర్‌లందరి కోసం యాప్‌లను అప్‌డేట్ చేయవచ్చు. యాక్సెసిబిలిటీ సెట్టింగ్‌లు, సర్వీస్‌లు కొత్త యూజర్‌కి బదిలీ కాకపోవచ్చు."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్‌లను క్రియేట్ చేయడం ద్వారా మీరు ఈ పరికరాన్ని ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్‌కు‌ వారికంటూ ప్రత్యేక స్పేస్ ఉంటుంది, వారు ఆ స్పేస్‌ను యాప్‌లు, వాల్‌పేపర్ మొదలైనవాటితో అనుకూలంగా మార్చుకోవచ్చు. యూజర్‌లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్‌లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్‌ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్పేస్‌ను సెట్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగిలిన యూజర్‌లందరి కోసం యాప్‌లను అప్‌డేట్ చేయవచ్చు. యాక్సెసిబిలిటీ సెట్టింగ్‌లు, సర్వీస్‌లు కొత్త యూజర్‌కి బదిలీ కాకపోవచ్చు."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"మీరు కొత్త యూజర్‌ను జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్‌ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా యూజర్ల కోసం యాప్‌లను అప్‌డేట్‌ చేయగలరు."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"ఈ యూజర్‌ను అడ్మిన్ చేయాలా?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"యూజర్‌లకు లేని ప్రత్యేక హక్కులు అడ్మిన్‌లకు ఉంటాయి. అడ్మిన్, యూజర్‌లందరినీ మేనేజ్ చేయగలరు, ఈ పరికరాన్ని అప్‌డేట్ లేదా రీసెట్ చేయగలరు, సెట్టింగ్‌లను మార్చగలరు, ఇన్‌స్టాల్ అయ్యి ఉండే యాప్‌లన్నింటినీ చూడగలరు, ఇతరులకు అడ్మిన్ హక్కులను ఇవ్వగలరు, లేదా ఉపసంహరించగలరు."</string>
- <string name="user_grant_admin_button" msgid="5441486731331725756">"అడ్మిన్‌గా చేయాలి"</string>
+ <string name="user_grant_admin_button" msgid="5441486731331725756">"అడ్మిన్‌గా చేయండి"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"యూజర్‌ను ఇప్పుడే సెటప్ చేయాలా?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి స్టోరేజ్‌ స్థలాన్ని సెటప్ చేయండి"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ఇప్పుడు ప్రొఫైల్‌ను సెటప్ చేయాలా?"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4e65699d53c8..8335cbafd0af 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"เสียง HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"เสียง HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"เครื่องช่วยฟัง"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"เชื่อมต่อกับเครื่องช่วยฟังแล้ว"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"เชื่อมต่อกับ LE Audio แล้ว"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"เชื่อมต่อกับระบบเสียงของสื่อแล้ว"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"เลือกโปรไฟล์"</string>
<string name="category_personal" msgid="6236798763159385225">"ส่วนตัว"</string>
<string name="category_work" msgid="4014193632325996115">"งาน"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"โคลน"</string>
<string name="development_settings_title" msgid="140296922921597393">"ตัวเลือกสำหรับนักพัฒนาแอป"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"เมื่อสักครู่"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"โทรศัพท์เครื่องนี้"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"แท็บเล็ตเครื่องนี้"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"โทรศัพท์เครื่องนี้"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"เล่นในอุปกรณ์นี้ไม่ได้"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"อัปเกรดบัญชีเพื่อเปลี่ยน"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index c57411885d91..dd729de51183 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Mga Hearing Aid"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Nakakonekta sa Mga Hearing Aid"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Nakakonekta sa LE audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Konektado sa media audio"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Pumili ng profile"</string>
<string name="category_personal" msgid="6236798763159385225">"Personal"</string>
<string name="category_work" msgid="4014193632325996115">"Trabaho"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"I-clone"</string>
<string name="development_settings_title" msgid="140296922921597393">"Mga opsyon ng developer"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"I-enable ang mga opsyon ng developer"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Magtakda ng mga pagpipilian para sa pagbuo ng app"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Ngayon lang"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ang teleponong ito"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ang tablet na ito"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ang teleponong ito"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Hindi ma-play sa device na ito"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"I-upgrade ang account para lumipat"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c6a5890def16..a2417ed5f036 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ses"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"İşitme Cihazları"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"İşitme Cihazlarına Bağlandı"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio\'ya bağlandı"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Medya sesine bağlanıldı"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Profil seçin"</string>
<string name="category_personal" msgid="6236798763159385225">"Kişisel"</string>
<string name="category_work" msgid="4014193632325996115">"İş"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
<string name="development_settings_title" msgid="140296922921597393">"Geliştirici seçenekleri"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Geliştirici seçeneklerini etkinleştir"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Uygulama geliştirme için seçenekleri ayarla"</string>
@@ -547,10 +545,16 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Az önce"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Bu telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Bu tablet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oynatılamıyor"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Geçiş yapmak için hesabı yükseltin"</string>
- <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"İndirilenler burada oynatılamıyor"</string>
+ <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"İndirilenler burada oynatılamaz"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamdan sonra tekrar deneyin"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Burada oynatmak için cihazı uyandırın"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"Cihaz, oynatma işlemini onaylamadı"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 63af040f300d..b5c31f4ec516 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-аудіо: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-аудіо"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слухові апарати"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Підключено до слухових апаратів"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Підключено до LE Audio"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Підключено до аудіоджерела"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Скасувати"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Якщо ви під’єднаєте інший пристрій, він матиме доступ до ваших контактів та історії дзвінків."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не вдалося створити пару з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Помилка підключення до пристрою <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправильний PIN-код чи ключ доступу."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не підключено пристрій <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправильний PIN-код чи ключ доступу."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Неможливо зв’язатися з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Створ. пари відхилено <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Комп’ютер"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Вибрати профіль"</string>
<string name="category_personal" msgid="6236798763159385225">"Особисте"</string>
<string name="category_work" msgid="4014193632325996115">"Робоче"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Копія профілю"</string>
<string name="development_settings_title" msgid="140296922921597393">"Параметри розробника"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Увімкнути параметри розробника"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Установити параметри для розробки програми"</string>
@@ -547,14 +545,20 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Щойно"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Цей телефон"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Цей планшет"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Цей телефон"</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>
+ <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>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Повторіть спробу після реклами"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Виведіть пристрій із режиму сну, щоб відтворювати медіаконтент"</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Пристрій не схвалений для відтворення медіаконтенту"</string>
- <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"На пристрої не можна відтворювати цей медіафайл"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Виведіть із режиму сну, щоб відтворювати"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Не схвалено для відтворення"</string>
+ <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Цей медіаконтент не підтримується"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
<string name="help_label" msgid="3528360748637781274">"Довідка й відгуки"</string>
@@ -577,7 +581,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"Користувач"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"Профіль з обмеженням"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"Додати нового користувача?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"Цим пристроєм можуть користуватися кілька людей. Для цього потрібно створити додаткові профілі. Власник профілю може налаштувати його на свій смак: вибрати фоновий малюнок, установити потрібні додатки тощо. Користувачі також можуть налаштовувати певні параметри пристрою (як-от Wi-Fi), які застосовуватимуться до решти профілів.\n\nПісля створення новий профіль потрібно налаштувати.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів. Налаштування спеціальних можливостей і сервісів можуть не передаватися новому користувачеві."</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"Цим пристроєм можуть користуватися кілька людей. Для цього потрібно створити додаткові профілі. Власник профілю може налаштувати його на свій смак: вибрати фоновий малюнок, установити потрібні додатки тощо. Користувачі також можуть налаштовувати певні параметри пристрою (як-от Wi-Fi), які застосовуватимуться до решти профілів.\n\nПісля створення новий профіль потрібно налаштувати.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів. Налаштування й сервіси доступності можуть не передаватися новому користувачеві."</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
<string name="user_grant_admin_title" msgid="5157031020083343984">"Надати цьому користувачу права адміністратора?"</string>
<string name="user_grant_admin_message" msgid="1673791931033486709">"Адміністратори, на відміну від звичайних користувачів, мають спеціальні права. Вони можуть керувати всіма користувачами, оновлювати, скидати чи змінювати налаштування цього пристрою, переглядати всі встановлені додатки, а також надавати іншим користувачам права адміністратора або відкликати їх."</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 4991022db5e1..fea22aa5dc96 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"ابھی ابھی"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"یہ فون"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"یہ ٹیبلیٹ"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"یہ فون"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"اس آلے پر چلایا نہیں جا سکتا"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"سوئچ کرنے کے لیے اکاؤنٹ اپ گریڈ کریں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index d4d0bbc0b869..312a22e12d68 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -545,13 +545,19 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Hozir"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Shu telefon"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Shu planshet"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Shu telefon"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu qurilmada ijro etilmaydi"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Oʻtish uchun hisobingizni yangilang"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Yuklab olingan fayllar ijro etilmaydi"</string>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamadan keyin qayta urining"</string>
<string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Ijro etish uchun qurilmani uyqu rejimidan chiqaring."</string>
- <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Qurilmaga ijro etish uchun ruxsat berilmagan"</string>
+ <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Qurilmada ijro ruxsati yoʻq"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Media fayl ijro etilmaydi"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index c2615501dff9..b16f200155d5 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -115,8 +115,7 @@
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Âm thanh HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Thiết bị trợ thính"</string>
- <!-- no translation found for bluetooth_profile_le_audio (1725521360076451751) -->
- <skip />
+ <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Âm thanh năng lượng thấp"</string>
<string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Đã kết nối với Thiết bị trợ thính"</string>
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Đã kết nối với âm thanh LE"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh nội dung nghe nhìn"</string>
@@ -142,7 +141,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Hủy"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Ghép nối giúp bạn có thể truy cập danh bạ và nhật ký cuộc gọi của mình khi được kết nối."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g> do mã PIN hoặc mã xác nhận không đúng."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g> do mã PIN hoặc mã truy cập không đúng."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Không thể kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Ghép nối bị <xliff:g id="DEVICE_NAME">%1$s</xliff:g> từ chối."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Máy tính"</string>
@@ -216,8 +215,7 @@
<string name="choose_profile" msgid="343803890897657450">"Chọn hồ sơ"</string>
<string name="category_personal" msgid="6236798763159385225">"Cá nhân"</string>
<string name="category_work" msgid="4014193632325996115">"Công việc"</string>
- <!-- no translation found for category_clone (1554511758987195974) -->
- <skip />
+ <string name="category_clone" msgid="1554511758987195974">"Nhân bản"</string>
<string name="development_settings_title" msgid="140296922921597393">"Tùy chọn cho nhà phát triển"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Bật tùy chọn nhà phát triển"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string>
@@ -547,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Vừa xong"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Điện thoại này"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Máy tính bảng này"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Điện thoại này"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Không phát được trên thiết bị này"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nâng cấp tài khoản để chuyển đổi"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index ac09ede1189d..d266d142e904 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -111,7 +111,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"用于联系人信息和通话记录分享"</string>
<string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"共享互联网连接"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"短信"</string>
- <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取权限"</string>
+ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡访问权限"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD 音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD 音频"</string>
<string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"助听器"</string>
@@ -455,7 +455,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根据您的使用情况,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"目前电量为 <xliff:g id="LEVEL">%2$s</xliff:g>,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"直到<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可以用到 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"刚刚"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"这部手机"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"这台平板电脑"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"这部手机"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"无法在此设备上播放"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"升级帐号后才能切换"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 1412dcdb04ff..be7c044f4a2e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -545,12 +545,18 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"此手機"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"此平板電腦"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"這部手機"</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>
<string name="media_output_status_try_after_ad" msgid="8312579066856015441">"請在廣告結束後再試一次"</string>
- <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"喚醒裝置即可在此播放"</string>
+ <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"必須喚醒裝置才能在此播放"</string>
<string name="media_output_status_unauthorized" msgid="5880222828273853838">"裝置未獲核准播放"</string>
<string name="media_output_status_track_unsupported" msgid="5576313219317709664">"無法在此播放此媒體內容"</string>
<string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連接,請關閉裝置然後重新開機"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 2a04ea9d39a6..59105e5ac0ba 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"這支手機"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"這台平板電腦"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"這支手機"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"無法在這部裝置上播放"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"請升級要切換的帳戶"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 80f4d505a294..87cf1f7e58a9 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -545,6 +545,12 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Khona manje"</string>
<string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Le foni"</string>
<string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Le thebulethi"</string>
+ <!-- no translation found for media_transfer_dock_speaker_device_name (2856219597113881950) -->
+ <skip />
+ <!-- no translation found for media_transfer_external_device_name (2588672258721846418) -->
+ <skip />
+ <!-- no translation found for media_transfer_default_device_name (4315604017399871828) -->
+ <skip />
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Le foni"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ayikwazi ukudlala kule divayisi"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Thuthukisa i-akhawunti ukuze ushintshe"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f581091f0f3e..9f884b277b5b 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -241,12 +241,12 @@
<!-- Bluetooth settings. Similar to bluetooth_profile_a2dp_high_quality, but used when the device supports high quality audio but we don't know which codec that will be used. -->
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec">HD audio</string>
- <!-- Bluetooth settings. The user-visible string that is used whenever referring to the Hearing Aid profile. -->
- <string name="bluetooth_profile_hearing_aid">Hearing Aids</string>
+ <!-- Bluetooth settings. The user-visible string that is used whenever referring to the Hearing aid profile. -->
+ <string name="bluetooth_profile_hearing_aid">Hearing aids</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the LE audio profile. -->
<string name="bluetooth_profile_le_audio">LE Audio</string>
- <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference when Hearing Aid is connected. -->
- <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to Hearing Aids</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the Hearing aid checkbox preference when hearing aid is connected. -->
+ <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to hearing aids</string>
<!-- Bluetooth settings. Connection options screen. The summary for the LE audio checkbox preference when LE audio is connected. -->
<string name="bluetooth_le_audio_profile_summary_connected">Connected to LE audio</string>
@@ -287,8 +287,8 @@
for the HID checkbox preference that describes how checking it
will set the HID profile as preferred. -->
<string name="bluetooth_hid_profile_summary_use_for">Use for input</string>
- <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference that describes how checking it will set the Hearing Aid profile as preferred. -->
- <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for Hearing Aids</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the Hearing aid checkbox preference that describes how checking it will set the hearing aid related profile as preferred. -->
+ <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for hearing aids</string>
<!-- Bluetooth settings. Connection options screen. The summary for the LE_AUDIO checkbox preference that describes how checking it will set the LE_AUDIO profile as preferred. -->
<string name="bluetooth_le_audio_profile_summary_use_for">Use for LE_AUDIO</string>
@@ -827,6 +827,11 @@
<!-- UI debug setting: show touches location summary [CHAR LIMIT=50] -->
<string name="show_touches_summary">Show visual feedback for taps</string>
+ <!-- UI debug setting: show key presses? [CHAR LIMIT=25] -->
+ <string name="show_key_presses">Show key presses</string>
+ <!-- UI debug setting: show physical key presses summary [CHAR LIMIT=50] -->
+ <string name="show_key_presses_summary">Show visual feedback for physical key presses</string>
+
<!-- UI debug setting: show where surface updates happen? [CHAR LIMIT=25] -->
<string name="show_screen_updates">Show surface updates</string>
<!-- UI debug setting: show surface updates summary [CHAR LIMIT=50] -->
@@ -1327,6 +1332,12 @@
<string name="media_transfer_this_device_name" product="default">This phone</string>
<!-- Name of the tablet device. [CHAR LIMIT=30] -->
<string name="media_transfer_this_device_name" product="tablet">This tablet</string>
+ <!-- Name of the dock device. [CHAR LIMIT=30] -->
+ <string name="media_transfer_dock_speaker_device_name">Dock speaker</string>
+ <!-- Default name of the external device. [CHAR LIMIT=30] -->
+ <string name="media_transfer_external_device_name">External Device</string>
+ <!-- Default name of the connected device. [CHAR LIMIT=30] -->
+ <string name="media_transfer_default_device_name">Connected device</string>
<!-- Name of the phone device with an active remote session. [CHAR LIMIT=30] -->
<string name="media_transfer_this_phone">This phone</string>
<!-- Sub status indicates device is not available due to an unknown error. [CHAR LIMIT=NONE] -->
diff --git a/packages/SettingsLib/res/values/styles.xml b/packages/SettingsLib/res/values/styles.xml
index 2584be725747..4ac4aae8f2ab 100644
--- a/packages/SettingsLib/res/values/styles.xml
+++ b/packages/SettingsLib/res/values/styles.xml
@@ -17,6 +17,7 @@
<resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="TextAppearanceSmall">
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="TextAppearanceMedium">
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
@@ -91,7 +92,7 @@
<item name="android:ellipsize">end</item>
</style>
- <style name="DialogButtonPositive" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <style name="DialogButtonPositive">
<item name="android:buttonCornerRadius">0dp</item>
<item name="android:background">@drawable/dialog_btn_filled</item>
<item name="android:textColor">?androidprv:attr/textColorOnAccent</item>
@@ -105,7 +106,6 @@
<style name="DialogButtonNegative">
<item name="android:buttonCornerRadius">28dp</item>
<item name="android:background">@drawable/dialog_btn_outline</item>
- <item name="android:buttonCornerRadius">28dp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">14sp</item>
<item name="android:lineHeight">20sp</item>
diff --git a/packages/SettingsLib/search/Android.bp b/packages/SettingsLib/search/Android.bp
index cfff519705f2..918d696fa481 100644
--- a/packages/SettingsLib/search/Android.bp
+++ b/packages/SettingsLib/search/Android.bp
@@ -7,8 +7,18 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
+java_library {
+ name: "SettingsLib-search-interface",
+ visibility: ["//visibility:private"],
+ srcs: ["interface-src/**/*.java"],
+ host_supported: true,
+}
+
android_library {
name: "SettingsLib-search",
+ static_libs: [
+ "SettingsLib-search-interface",
+ ],
srcs: ["src/**/*.java"],
sdk_version: "system_current",
@@ -19,12 +29,10 @@ java_plugin {
name: "SettingsLib-annotation-processor",
processor_class: "com.android.settingslib.search.IndexableProcessor",
static_libs: [
+ "SettingsLib-search-interface",
"javapoet",
],
- srcs: [
- "processor-src/**/*.java",
- "src/com/android/settingslib/search/SearchIndexable.java",
- ],
+ srcs: ["processor-src/**/*.java"],
java_resource_dirs: ["resources"],
}
diff --git a/packages/SettingsLib/search/common.mk b/packages/SettingsLib/search/common.mk
deleted file mode 100644
index 05226db5cb91..000000000000
--- a/packages/SettingsLib/search/common.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Include this file to generate SearchIndexableResourcesImpl
-
-LOCAL_ANNOTATION_PROCESSORS += \
- SettingsLib-annotation-processor
-
-LOCAL_ANNOTATION_PROCESSOR_CLASSES += \
- com.android.settingslib.search.IndexableProcessor
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- SettingsLib-search
diff --git a/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexable.java b/packages/SettingsLib/search/interface-src/com/android/settingslib/search/SearchIndexable.java
index 638fa3e98138..174f33709b02 100644
--- a/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexable.java
+++ b/packages/SettingsLib/search/interface-src/com/android/settingslib/search/SearchIndexable.java
@@ -27,7 +27,7 @@ public @interface SearchIndexable {
/**
* Bitfield for the form factors this class should be considered indexable for.
* Default is {@link #ALL}.
- *
+ * <p>
* TODO: actually use this value somehow
*/
int forTarget() default ALL;
@@ -35,27 +35,27 @@ public @interface SearchIndexable {
/**
* Indicates that the class should be considered indexable for Mobile.
*/
- int MOBILE = 1<<0;
+ int MOBILE = 1 << 0;
/**
* Indicates that the class should be considered indexable for TV.
*/
- int TV = 1<<1;
+ int TV = 1 << 1;
/**
* Indicates that the class should be considered indexable for Wear.
*/
- int WEAR = 1<<2;
+ int WEAR = 1 << 2;
/**
* Indicates that the class should be considered indexable for Auto.
*/
- int AUTO = 1<<3;
+ int AUTO = 1 << 3;
/**
* Indicates that the class should be considered indexable for ARC++.
*/
- int ARC = 1<<4;
+ int ARC = 1 << 4;
/**
* Indicates that the class should be considered indexable for all targets.
diff --git a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
index e92157e7c867..fa43915deb6a 100644
--- a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
+++ b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java
@@ -34,6 +34,7 @@ import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
@@ -48,10 +49,11 @@ import javax.tools.Diagnostic.Kind;
* subclasses.
*/
@SupportedSourceVersion(SourceVersion.RELEASE_17)
+@SupportedOptions(IndexableProcessor.PACKAGE_KEY)
@SupportedAnnotationTypes({"com.android.settingslib.search.SearchIndexable"})
public class IndexableProcessor extends AbstractProcessor {
- private static final String PACKAGE = "com.android.settingslib.search";
+ private static final String SETTINGSLIB_SEARCH_PACKAGE = "com.android.settingslib.search";
private static final String CLASS_BASE = "SearchIndexableResourcesBase";
private static final String CLASS_MOBILE = "SearchIndexableResourcesMobile";
private static final String CLASS_TV = "SearchIndexableResourcesTv";
@@ -59,6 +61,9 @@ public class IndexableProcessor extends AbstractProcessor {
private static final String CLASS_AUTO = "SearchIndexableResourcesAuto";
private static final String CLASS_ARC = "SearchIndexableResourcesArc";
+ static final String PACKAGE_KEY = "com.android.settingslib.search.processor.package";
+
+ private String mPackage;
private Filer mFiler;
private Messager mMessager;
private boolean mRanOnce;
@@ -72,7 +77,8 @@ public class IndexableProcessor extends AbstractProcessor {
}
mRanOnce = true;
- final ClassName searchIndexableData = ClassName.get(PACKAGE, "SearchIndexableData");
+ final ClassName searchIndexableData =
+ ClassName.get(SETTINGSLIB_SEARCH_PACKAGE, "SearchIndexableData");
final FieldSpec providers = FieldSpec.builder(
ParameterizedTypeName.get(
@@ -130,7 +136,7 @@ public class IndexableProcessor extends AbstractProcessor {
builder = arcConstructorBuilder;
}
builder.addCode(
- "$N(new SearchIndexableData($L.class, $L"
+ "$N(new com.android.settingslib.search.SearchIndexableData($L.class, $L"
+ ".SEARCH_INDEX_DATA_PROVIDER));\n",
addIndex, className, className);
} else {
@@ -150,50 +156,51 @@ public class IndexableProcessor extends AbstractProcessor {
final TypeSpec baseClass = TypeSpec.classBuilder(CLASS_BASE)
.addModifiers(Modifier.PUBLIC)
- .addSuperinterface(ClassName.get(PACKAGE, "SearchIndexableResources"))
+ .addSuperinterface(
+ ClassName.get(SETTINGSLIB_SEARCH_PACKAGE, "SearchIndexableResources"))
.addField(providers)
.addMethod(baseConstructorBuilder.build())
.addMethod(addIndex)
.addMethod(getProviderValues)
.build();
- final JavaFile searchIndexableResourcesBase = JavaFile.builder(PACKAGE, baseClass).build();
+ final JavaFile searchIndexableResourcesBase = JavaFile.builder(mPackage, baseClass).build();
- final JavaFile searchIndexableResourcesMobile = JavaFile.builder(PACKAGE,
+ final JavaFile searchIndexableResourcesMobile = JavaFile.builder(mPackage,
TypeSpec.classBuilder(CLASS_MOBILE)
.addModifiers(Modifier.PUBLIC)
- .superclass(ClassName.get(PACKAGE, baseClass.name))
+ .superclass(ClassName.get(mPackage, baseClass.name))
.addMethod(mobileConstructorBuilder.build())
.build())
.build();
- final JavaFile searchIndexableResourcesTv = JavaFile.builder(PACKAGE,
+ final JavaFile searchIndexableResourcesTv = JavaFile.builder(mPackage,
TypeSpec.classBuilder(CLASS_TV)
.addModifiers(Modifier.PUBLIC)
- .superclass(ClassName.get(PACKAGE, baseClass.name))
+ .superclass(ClassName.get(mPackage, baseClass.name))
.addMethod(tvConstructorBuilder.build())
.build())
.build();
- final JavaFile searchIndexableResourcesWear = JavaFile.builder(PACKAGE,
+ final JavaFile searchIndexableResourcesWear = JavaFile.builder(mPackage,
TypeSpec.classBuilder(CLASS_WEAR)
.addModifiers(Modifier.PUBLIC)
- .superclass(ClassName.get(PACKAGE, baseClass.name))
+ .superclass(ClassName.get(mPackage, baseClass.name))
.addMethod(wearConstructorBuilder.build())
.build())
.build();
- final JavaFile searchIndexableResourcesAuto = JavaFile.builder(PACKAGE,
+ final JavaFile searchIndexableResourcesAuto = JavaFile.builder(mPackage,
TypeSpec.classBuilder(CLASS_AUTO)
.addModifiers(Modifier.PUBLIC)
- .superclass(ClassName.get(PACKAGE, baseClass.name))
+ .superclass(ClassName.get(mPackage, baseClass.name))
.addMethod(autoConstructorBuilder.build())
.build())
.build();
- final JavaFile searchIndexableResourcesArc = JavaFile.builder(PACKAGE,
+ final JavaFile searchIndexableResourcesArc = JavaFile.builder(mPackage,
TypeSpec.classBuilder(CLASS_ARC)
.addModifiers(Modifier.PUBLIC)
- .superclass(ClassName.get(PACKAGE, baseClass.name))
+ .superclass(ClassName.get(mPackage, baseClass.name))
.addMethod(arcConstructorBuilder.build())
.build())
.build();
@@ -214,6 +221,8 @@ public class IndexableProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
+ mPackage = processingEnvironment.getOptions()
+ .getOrDefault(PACKAGE_KEY, SETTINGSLIB_SEARCH_PACKAGE);
mFiler = processingEnvironment.getFiler();
mMessager = processingEnvironment.getMessager();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index fe8988385453..6eb2f3834858 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -484,8 +484,9 @@ public class ApplicationsState {
if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock...");
synchronized (mEntriesMap) {
AppEntry entry = null;
- if (mEntriesMap.contains(userId)) {
- entry = mEntriesMap.get(userId).get(packageName);
+ HashMap<String, AppEntry> userEntriesMap = mEntriesMap.get(userId);
+ if (userEntriesMap != null) {
+ entry = userEntriesMap.get(packageName);
}
if (entry == null) {
ApplicationInfo info = getAppInfoLocked(packageName, userId);
@@ -735,8 +736,9 @@ public class ApplicationsState {
private AppEntry getEntryLocked(ApplicationInfo info) {
int userId = UserHandle.getUserId(info.uid);
AppEntry entry = null;
- if (mEntriesMap.contains(userId)) {
- entry = mEntriesMap.get(userId).get(info.packageName);
+ HashMap<String, AppEntry> userEntriesMap = mEntriesMap.get(userId);
+ if (userEntriesMap != null) {
+ entry = userEntriesMap.get(info.packageName);
}
if (DEBUG) {
Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
@@ -752,8 +754,11 @@ public class ApplicationsState {
Log.i(TAG, "Creating AppEntry for " + info.packageName);
}
entry = new AppEntry(mContext, info, mCurId++);
- mEntriesMap.get(userId).put(info.packageName, entry);
- mAppEntries.add(entry);
+ userEntriesMap = mEntriesMap.get(userId);
+ if (userEntriesMap != null) {
+ userEntriesMap.put(info.packageName, entry);
+ mAppEntries.add(entry);
+ }
} else if (entry.info != info) {
entry.info = info;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
index a80061efb19a..1ff2befd19ed 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
@@ -44,38 +44,4 @@ public final class BluetoothBroadcastUtils {
* Bluetooth scheme.
*/
public static final String SCHEME_BT_BROADCAST_METADATA = "BT:";
-
- // BluetoothLeBroadcastMetadata
- static final String PREFIX_BT_ADDRESS_TYPE = "T:";
- static final String PREFIX_BT_DEVICE = "D:";
- static final String PREFIX_BT_ADVERTISING_SID = "AS:";
- static final String PREFIX_BT_BROADCAST_ID = "B:";
- static final String PREFIX_BT_SYNC_INTERVAL = "SI:";
- static final String PREFIX_BT_IS_ENCRYPTED = "E:";
- static final String PREFIX_BT_BROADCAST_CODE = "C:";
- static final String PREFIX_BT_PRESENTATION_DELAY = "PD:";
- static final String PREFIX_BT_SUBGROUPS = "SG:";
- static final String PREFIX_BT_ANDROID_VERSION = "V:";
-
- // BluetoothLeBroadcastSubgroup
- static final String PREFIX_BTSG_CODEC_ID = "CID:";
- static final String PREFIX_BTSG_CODEC_CONFIG = "CC:";
- static final String PREFIX_BTSG_AUDIO_CONTENT = "AC:";
- static final String PREFIX_BTSG_CHANNEL_PREF = "CP:";
- static final String PREFIX_BTSG_BROADCAST_CHANNEL = "BC:";
-
- // BluetoothLeAudioCodecConfigMetadata
- static final String PREFIX_BTCC_AUDIO_LOCATION = "AL:";
- static final String PREFIX_BTCC_RAW_METADATA = "CCRM:";
-
- // BluetoothLeAudioContentMetadata
- static final String PREFIX_BTAC_PROGRAM_INFO = "PI:";
- static final String PREFIX_BTAC_LANGUAGE = "L:";
- static final String PREFIX_BTAC_RAW_METADATA = "ACRM:";
-
- // BluetoothLeBroadcastChannel
- static final String PREFIX_BTBC_CHANNEL_INDEX = "CI:";
- static final String PREFIX_BTBC_CODEC_CONFIG = "BCCM:";
-
- static final String DELIMITER_QR_CODE = ";";
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
new file mode 100644
index 000000000000..9bb11f8da645
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.bluetooth
+
+import android.annotation.TargetApi
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothLeAudioCodecConfigMetadata
+import android.bluetooth.BluetoothLeAudioContentMetadata
+import android.bluetooth.BluetoothLeBroadcastChannel
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.bluetooth.BluetoothLeBroadcastSubgroup
+import android.os.Build
+import android.util.Base64
+import android.util.Log
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA
+
+object BluetoothLeBroadcastMetadataExt {
+ private const val TAG = "BtLeBroadcastMetadataExt"
+
+ // BluetoothLeBroadcastMetadata
+ private const val KEY_BT_QR_VER = "R"
+ private const val KEY_BT_ADDRESS_TYPE = "T"
+ private const val KEY_BT_DEVICE = "D"
+ private const val KEY_BT_ADVERTISING_SID = "AS"
+ private const val KEY_BT_BROADCAST_ID = "B"
+ private const val KEY_BT_BROADCAST_NAME = "BN"
+ private const val KEY_BT_PUBLIC_BROADCAST_DATA = "PM"
+ private const val KEY_BT_SYNC_INTERVAL = "SI"
+ private const val KEY_BT_BROADCAST_CODE = "C"
+ private const val KEY_BT_SUBGROUPS = "SG"
+ private const val KEY_BT_VENDOR_SPECIFIC = "V"
+ private const val KEY_BT_ANDROID_VERSION = "VN"
+
+ // Subgroup data
+ private const val KEY_BTSG_BIS_SYNC = "BS"
+ private const val KEY_BTSG_BIS_MASK = "BM"
+ private const val KEY_BTSG_AUDIO_CONTENT = "AC"
+
+ // Vendor specific data
+ private const val KEY_BTVSD_COMPANY_ID = "VI"
+ private const val KEY_BTVSD_VENDOR_DATA = "VD"
+
+ private const val DELIMITER_KEY_VALUE = ":"
+ private const val DELIMITER_BT_LEVEL_1 = ";"
+ private const val DELIMITER_BT_LEVEL_2 = ","
+
+ private const val SUFFIX_QR_CODE = ";;"
+
+ private const val ANDROID_VER = "U"
+ private const val QR_CODE_VER = 0x010000
+
+ // BT constants
+ private const val BIS_SYNC_MAX_CHANNEL = 32
+ private const val BIS_SYNC_NO_PREFERENCE = 0xFFFFFFFFu
+ private const val SUBGROUP_LC3_CODEC_ID = 0x6L
+
+ /**
+ * Converts [BluetoothLeBroadcastMetadata] to QR code string.
+ *
+ * QR code string will prefix with "BT:".
+ */
+ fun BluetoothLeBroadcastMetadata.toQrCodeString(): String {
+ val entries = mutableListOf<Pair<String, String>>()
+ entries.add(Pair(KEY_BT_QR_VER, QR_CODE_VER.toString()))
+ entries.add(Pair(KEY_BT_ADDRESS_TYPE, this.sourceAddressType.toString()))
+ entries.add(Pair(KEY_BT_DEVICE, this.sourceDevice.address.replace(":", "-")))
+ entries.add(Pair(KEY_BT_ADVERTISING_SID, this.sourceAdvertisingSid.toString()))
+ entries.add(Pair(KEY_BT_BROADCAST_ID, this.broadcastId.toString()))
+ if (this.broadcastName != null) {
+ entries.add(Pair(KEY_BT_BROADCAST_NAME, Base64.encodeToString(
+ this.broadcastName?.toByteArray(Charsets.UTF_8), Base64.NO_WRAP)))
+ }
+ if (this.publicBroadcastMetadata != null) {
+ entries.add(Pair(KEY_BT_PUBLIC_BROADCAST_DATA, Base64.encodeToString(
+ this.publicBroadcastMetadata?.rawMetadata, Base64.NO_WRAP)))
+ }
+ entries.add(Pair(KEY_BT_SYNC_INTERVAL, this.paSyncInterval.toString()))
+ if (this.broadcastCode != null) {
+ entries.add(Pair(KEY_BT_BROADCAST_CODE,
+ Base64.encodeToString(this.broadcastCode, Base64.NO_WRAP)))
+ }
+ this.subgroups.forEach {
+ subgroup -> entries.add(Pair(KEY_BT_SUBGROUPS, subgroup.toQrCodeString())) }
+ entries.add(Pair(KEY_BT_ANDROID_VERSION, ANDROID_VER))
+ val qrCodeString = SCHEME_BT_BROADCAST_METADATA +
+ entries.toQrCodeString(DELIMITER_BT_LEVEL_1) + SUFFIX_QR_CODE
+ Log.d(TAG, "Generated QR string : $qrCodeString")
+ return qrCodeString
+ }
+
+ /**
+ * Converts QR code string to [BluetoothLeBroadcastMetadata].
+ *
+ * QR code string should prefix with "BT:BluetoothLeBroadcastMetadata:".
+ */
+ fun convertToBroadcastMetadata(qrCodeString: String): BluetoothLeBroadcastMetadata? {
+ if (!qrCodeString.startsWith(SCHEME_BT_BROADCAST_METADATA)) {
+ Log.e(TAG, "String \"$qrCodeString\" does not begin with " +
+ "\"$SCHEME_BT_BROADCAST_METADATA\"")
+ return null
+ }
+ return try {
+ Log.d(TAG, "Parsing QR string: $qrCodeString")
+ val strippedString =
+ qrCodeString.removePrefix(SCHEME_BT_BROADCAST_METADATA)
+ .removeSuffix(SUFFIX_QR_CODE)
+ Log.d(TAG, "Stripped to: $strippedString")
+ parseQrCodeToMetadata(strippedString)
+ } catch (e: Exception) {
+ Log.w(TAG, "Cannot parse: $qrCodeString", e)
+ null
+ }
+ }
+
+ private fun BluetoothLeBroadcastSubgroup.toQrCodeString(): String {
+ val entries = mutableListOf<Pair<String, String>>()
+ entries.add(Pair(KEY_BTSG_BIS_SYNC, getBisSyncFromChannels(this.channels).toString()))
+ entries.add(Pair(KEY_BTSG_BIS_MASK, getBisMaskFromChannels(this.channels).toString()))
+ entries.add(Pair(KEY_BTSG_AUDIO_CONTENT,
+ Base64.encodeToString(this.contentMetadata.rawMetadata, Base64.NO_WRAP)))
+ return entries.toQrCodeString(DELIMITER_BT_LEVEL_2)
+ }
+
+ private fun List<Pair<String, String>>.toQrCodeString(delimiter: String): String {
+ val entryStrings = this.map{ it.first + DELIMITER_KEY_VALUE + it.second }
+ return entryStrings.joinToString(separator = delimiter)
+ }
+
+ @TargetApi(Build.VERSION_CODES.TIRAMISU)
+ private fun parseQrCodeToMetadata(input: String): BluetoothLeBroadcastMetadata {
+ // Split into a list of list
+ val level1Fields = input.split(DELIMITER_BT_LEVEL_1)
+ .map{it.split(DELIMITER_KEY_VALUE, limit = 2)}
+ var qrCodeVersion = -1
+ var sourceAddrType = BluetoothDevice.ADDRESS_TYPE_UNKNOWN
+ var sourceAddrString: String? = null
+ var sourceAdvertiserSid = -1
+ var broadcastId = -1
+ var broadcastName: String? = null
+ var publicBroadcastMetadata: BluetoothLeAudioContentMetadata? = null
+ var paSyncInterval = -1
+ var broadcastCode: ByteArray? = null
+ // List of VendorID -> Data Pairs
+ var vendorDataList = mutableListOf<Pair<Int, ByteArray?>>()
+ var androidVersion: String? = null
+ val builder = BluetoothLeBroadcastMetadata.Builder()
+
+ for (field: List<String> in level1Fields) {
+ if (field.isEmpty()) {
+ continue
+ }
+ val key = field[0]
+ // Ignore 3rd value and after
+ val value = if (field.size > 1) field[1] else ""
+ when (key) {
+ KEY_BT_QR_VER -> {
+ require(qrCodeVersion == -1) { "Duplicate qrCodeVersion: $input" }
+ qrCodeVersion = value.toInt()
+ }
+ KEY_BT_ADDRESS_TYPE -> {
+ require(sourceAddrType == BluetoothDevice.ADDRESS_TYPE_UNKNOWN) {
+ "Duplicate sourceAddrType: $input"
+ }
+ sourceAddrType = value.toInt()
+ }
+ KEY_BT_DEVICE -> {
+ require(sourceAddrString == null) { "Duplicate sourceAddr: $input" }
+ sourceAddrString = value.replace("-", ":")
+ }
+ KEY_BT_ADVERTISING_SID -> {
+ require(sourceAdvertiserSid == -1) { "Duplicate sourceAdvertiserSid: $input" }
+ sourceAdvertiserSid = value.toInt()
+ }
+ KEY_BT_BROADCAST_ID -> {
+ require(broadcastId == -1) { "Duplicate broadcastId: $input" }
+ broadcastId = value.toInt()
+ }
+ KEY_BT_BROADCAST_NAME -> {
+ require(broadcastName == null) { "Duplicate broadcastName: $input" }
+ broadcastName = String(Base64.decode(value, Base64.NO_WRAP))
+ }
+ KEY_BT_PUBLIC_BROADCAST_DATA -> {
+ require(publicBroadcastMetadata == null) {
+ "Duplicate publicBroadcastMetadata $input"
+ }
+ publicBroadcastMetadata = BluetoothLeAudioContentMetadata
+ .fromRawBytes(Base64.decode(value, Base64.NO_WRAP))
+ }
+ KEY_BT_SYNC_INTERVAL -> {
+ require(paSyncInterval == -1) { "Duplicate paSyncInterval: $input" }
+ paSyncInterval = value.toInt()
+ }
+ KEY_BT_BROADCAST_CODE -> {
+ require(broadcastCode == null) { "Duplicate broadcastCode: $input" }
+ broadcastCode = Base64.decode(value, Base64.NO_WRAP)
+ }
+ KEY_BT_ANDROID_VERSION -> {
+ require(androidVersion == null) { "Duplicate androidVersion: $input" }
+ androidVersion = value
+ Log.i(TAG, "QR code Android version: $androidVersion")
+ }
+ // Repeatable
+ KEY_BT_SUBGROUPS -> {
+ builder.addSubgroup(parseSubgroupData(value))
+ }
+ // Repeatable
+ KEY_BT_VENDOR_SPECIFIC -> {
+ vendorDataList.add(parseVendorData(value))
+ }
+ }
+ }
+ Log.d(TAG, "parseQrCodeToMetadata: sourceAddrType=$sourceAddrType, " +
+ "sourceAddr=$sourceAddrString, sourceAdvertiserSid=$sourceAdvertiserSid, " +
+ "broadcastId=$broadcastId, broadcastName=$broadcastName, " +
+ "publicBroadcastMetadata=${publicBroadcastMetadata != null}, " +
+ "paSyncInterval=$paSyncInterval, " +
+ "broadcastCode=${broadcastCode?.toString(Charsets.UTF_8)}")
+ Log.d(TAG, "Not used in current code, but part of the specification: " +
+ "qrCodeVersion=$qrCodeVersion, androidVersion=$androidVersion, " +
+ "vendorDataListSize=${vendorDataList.size}")
+ val adapter = BluetoothAdapter.getDefaultAdapter()
+ // add source device and set broadcast code
+ val device = adapter.getRemoteLeDevice(requireNotNull(sourceAddrString), sourceAddrType)
+ builder.apply {
+ setSourceDevice(device, sourceAddrType)
+ setSourceAdvertisingSid(sourceAdvertiserSid)
+ setBroadcastId(broadcastId)
+ setBroadcastName(broadcastName)
+ setPublicBroadcast(publicBroadcastMetadata != null)
+ setPublicBroadcastMetadata(publicBroadcastMetadata)
+ setPaSyncInterval(paSyncInterval)
+ setEncrypted(broadcastCode != null)
+ setBroadcastCode(broadcastCode)
+ // Presentation delay is unknown and not useful when adding source
+ // Broadcast sink needs to sync to the Broadcast source to get presentation delay
+ setPresentationDelayMicros(0)
+ }
+ return builder.build()
+ }
+
+ private fun parseSubgroupData(input: String): BluetoothLeBroadcastSubgroup {
+ Log.d(TAG, "parseSubgroupData: $input")
+ val fields = input.split(DELIMITER_BT_LEVEL_2)
+ var bisSync: UInt? = null
+ var bisMask: UInt? = null
+ var metadata: ByteArray? = null
+
+ fields.forEach { field ->
+ val(key, value) = field.split(DELIMITER_KEY_VALUE)
+ when (key) {
+ KEY_BTSG_BIS_SYNC -> {
+ require(bisSync == null) { "Duplicate bisSync: $input" }
+ bisSync = value.toUInt()
+ }
+ KEY_BTSG_BIS_MASK -> {
+ require(bisMask == null) { "Duplicate bisMask: $input" }
+ bisMask = value.toUInt()
+ }
+ KEY_BTSG_AUDIO_CONTENT -> {
+ require(metadata == null) { "Duplicate metadata: $input" }
+ metadata = Base64.decode(value, Base64.NO_WRAP)
+ }
+ }
+ }
+ val channels = convertToChannels(requireNotNull(bisSync), requireNotNull(bisMask))
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
+ .setAudioLocation(0).build()
+ return BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(SUBGROUP_LC3_CODEC_ID)
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(
+ BluetoothLeAudioContentMetadata.fromRawBytes(metadata ?: ByteArray(0)))
+ channels.forEach(::addChannel)
+ }.build()
+ }
+
+ private fun parseVendorData(input: String): Pair<Int, ByteArray?> {
+ var companyId = -1
+ var data: ByteArray? = null
+ val fields = input.split(DELIMITER_BT_LEVEL_2)
+ fields.forEach { field ->
+ val(key, value) = field.split(DELIMITER_KEY_VALUE)
+ when (key) {
+ KEY_BTVSD_COMPANY_ID -> {
+ require(companyId == -1) { "Duplicate companyId: $input" }
+ companyId = value.toInt()
+ }
+ KEY_BTVSD_VENDOR_DATA -> {
+ require(data == null) { "Duplicate data: $input" }
+ data = Base64.decode(value, Base64.NO_WRAP)
+ }
+ }
+ }
+ return Pair(companyId, data)
+ }
+
+ private fun getBisSyncFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
+ var bisSync = 0u
+ // channel index starts from 1
+ channels.forEach { channel ->
+ if (channel.isSelected && channel.channelIndex > 0) {
+ bisSync = bisSync or (1u shl (channel.channelIndex - 1))
+ }
+ }
+ // No channel is selected means no preference on Android platform
+ return if (bisSync == 0u) BIS_SYNC_NO_PREFERENCE else bisSync
+ }
+
+ private fun getBisMaskFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
+ var bisMask = 0u
+ // channel index starts from 1
+ channels.forEach { channel ->
+ if (channel.channelIndex > 0) {
+ bisMask = bisMask or (1u shl (channel.channelIndex - 1))
+ }
+ }
+ return bisMask
+ }
+
+ private fun convertToChannels(bisSync: UInt, bisMask: UInt):
+ List<BluetoothLeBroadcastChannel> {
+ Log.d(TAG, "convertToChannels: bisSync=$bisSync, bisMask=$bisMask")
+ var selectionMask = bisSync
+ if (bisSync != BIS_SYNC_NO_PREFERENCE) {
+ require(bisMask == (bisMask or bisSync)) {
+ "bisSync($bisSync) must select a subset of bisMask($bisMask) if it has preferences"
+ }
+ } else {
+ // No channel preference means no channel is selected
+ selectionMask = 0u
+ }
+ val channels = mutableListOf<BluetoothLeBroadcastChannel>()
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
+ .setAudioLocation(0).build()
+ for (i in 0 until BIS_SYNC_MAX_CHANNEL) {
+ val channelMask = 1u shl i
+ if ((bisMask and channelMask) != 0u) {
+ val channel = BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected((selectionMask and channelMask) != 0u)
+ setChannelIndex(i + 1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }
+ channels.add(channel.build())
+ }
+ }
+ return channels
+ }
+} \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
deleted file mode 100644
index 0630a2e515e0..000000000000
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.bluetooth;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeAudioCodecConfigMetadata;
-import android.bluetooth.BluetoothLeAudioContentMetadata;
-import android.bluetooth.BluetoothLeBroadcastChannel;
-import android.bluetooth.BluetoothLeBroadcastMetadata;
-import android.bluetooth.BluetoothLeBroadcastSubgroup;
-import android.util.Log;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class LocalBluetoothLeBroadcastMetadata {
- private static final boolean DEBUG = BluetoothUtils.D;
- private static final String TAG = "LocalBluetoothLeBroadcastMetadata";
- private static final String METADATA_START = "<";
- private static final String METADATA_END = ">";
- private static final String PATTERN_REGEX = "<(.*?)>";
- private static final String PATTERN_BT_BROADCAST_METADATA =
- "T:<(.*?)>;+D:<(.*?)>;+AS:<(.*?)>;+B:<(.*?)>;+SI:<(.*?)>;+E:<(.*?)>;+C:<(.*?)>;"
- + "+PD:<(.*?)>;+SG:(.*)";
- private static final String PATTERN_BT_SUBGROUP =
- "CID:<(.*?)>;+CC:<(.*?);>;+AC:<(.*?);>;+CP:<(.*?)>;+BC:<(.*)>;>;";
- private static final String PATTERN_BT_CHANNEL = "CI:<(.*?)>;+BCCM:<(.*?);>;";
-
- /* Index for BluetoothLeBroadcastMetadata */
- private static int MATCH_INDEX_ADDRESS_TYPE = 1;
- private static int MATCH_INDEX_DEVICE = 2;
- private static int MATCH_INDEX_ADVERTISING_SID = 3;
- private static int MATCH_INDEX_BROADCAST_ID = 4;
- private static int MATCH_INDEX_SYNC_INTERVAL = 5;
- private static int MATCH_INDEX_IS_ENCRYPTED = 6;
- private static int MATCH_INDEX_BROADCAST_CODE = 7;
- private static int MATCH_INDEX_PRESENTATION_DELAY = 8;
- private static int MATCH_INDEX_SUBGROUPS = 9;
-
- /* Index for BluetoothLeBroadcastSubgroup */
- private static int MATCH_INDEX_CODEC_ID = 1;
- private static int MATCH_INDEX_CODEC_CONFIG = 2;
- private static int MATCH_INDEX_AUDIO_CONTENT = 3;
- private static int MATCH_INDEX_CHANNEL_PREF = 4;
- private static int MATCH_INDEX_BROADCAST_CHANNEL = 5;
-
- /* Index for BluetoothLeAudioCodecConfigMetadata */
- private static int LIST_INDEX_AUDIO_LOCATION = 0;
- private static int LIST_INDEX_CODEC_CONFIG_RAW_METADATA = 1;
-
- /* Index for BluetoothLeAudioContentMetadata */
- private static int LIST_INDEX_PROGRAM_INFO = 0;
- private static int LIST_INDEX_LANGUAGE = 1;
- private static int LIST_INDEX_AUDIO_CONTENT_RAW_METADATA = 2;
-
- /* Index for BluetoothLeBroadcastChannel */
- private static int MATCH_INDEX_CHANNEL_INDEX = 1;
- private static int MATCH_INDEX_CHANNEL_CODEC_CONFIG = 2;
-
- private BluetoothLeBroadcastSubgroup mSubgroup;
- private List<BluetoothLeBroadcastSubgroup> mSubgroupList;
-
- // BluetoothLeBroadcastMetadata
- // Optional: Identity address type
- private int mSourceAddressType;
- // Optional: Must use identity address
- private BluetoothDevice mSourceDevice;
- private int mSourceAdvertisingSid;
- private int mBroadcastId;
- private int mPaSyncInterval;
- private int mPresentationDelayMicros;
- private boolean mIsEncrypted;
- private byte[] mBroadcastCode;
-
- // BluetoothLeBroadcastSubgroup
- private int mCodecId;
- private BluetoothLeAudioContentMetadata mContentMetadata;
- private BluetoothLeAudioCodecConfigMetadata mConfigMetadata;
- private Boolean mNoChannelPreference;
- private List<BluetoothLeBroadcastChannel> mChannel;
-
- // BluetoothLeAudioCodecConfigMetadata
- private long mAudioLocation;
- private byte[] mCodecConfigMetadata;
-
- // BluetoothLeAudioContentMetadata
- private String mLanguage;
- private String mProgramInfo;
- private byte[] mAudioContentMetadata;
-
- // BluetoothLeBroadcastChannel
- private boolean mIsSelected;
- private int mChannelIndex;
-
-
- LocalBluetoothLeBroadcastMetadata(BluetoothLeBroadcastMetadata metadata) {
- mSourceAddressType = metadata.getSourceAddressType();
- mSourceDevice = metadata.getSourceDevice();
- mSourceAdvertisingSid = metadata.getSourceAdvertisingSid();
- mBroadcastId = metadata.getBroadcastId();
- mPaSyncInterval = metadata.getPaSyncInterval();
- mIsEncrypted = metadata.isEncrypted();
- mBroadcastCode = metadata.getBroadcastCode();
- mPresentationDelayMicros = metadata.getPresentationDelayMicros();
- mSubgroupList = metadata.getSubgroups();
- }
-
- public LocalBluetoothLeBroadcastMetadata() {
- }
-
- public void setBroadcastCode(byte[] code) {
- mBroadcastCode = code;
- }
-
- public int getBroadcastId() {
- return mBroadcastId;
- }
-
- public String convertToQrCodeString() {
- String subgroupString = convertSubgroupToString(mSubgroupList);
- return new StringBuilder()
- .append(BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA)
- .append(BluetoothBroadcastUtils.PREFIX_BT_ADDRESS_TYPE)
- .append(METADATA_START).append(mSourceAddressType).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_DEVICE)
- .append(METADATA_START).append(mSourceDevice).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_ADVERTISING_SID)
- .append(METADATA_START).append(mSourceAdvertisingSid).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_BROADCAST_ID)
- .append(METADATA_START).append(mBroadcastId).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_SYNC_INTERVAL)
- .append(METADATA_START).append(mPaSyncInterval).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_IS_ENCRYPTED)
- .append(METADATA_START).append(mIsEncrypted).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_BROADCAST_CODE)
- .append(METADATA_START).append(Arrays.toString(mBroadcastCode)).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_PRESENTATION_DELAY)
- .append(METADATA_START).append(mPresentationDelayMicros).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BT_SUBGROUPS)
- .append(METADATA_START).append(subgroupString).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .toString();
- }
-
- private String convertSubgroupToString(List<BluetoothLeBroadcastSubgroup> subgroupList) {
- StringBuilder subgroupListBuilder = new StringBuilder();
- String subgroupString = "";
- for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
- String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
- String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
- boolean hasChannelPreference = subgroup.hasChannelPreference();
- String channels = convertChannelToString(subgroup.getChannels());
- subgroupString = new StringBuilder()
- .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
- .append(METADATA_START).append(subgroup.getCodecId()).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_CONFIG)
- .append(METADATA_START).append(audioCodec).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
- .append(METADATA_START).append(audioContent).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTSG_CHANNEL_PREF)
- .append(METADATA_START).append(hasChannelPreference).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
- .append(METADATA_START).append(channels).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .toString();
- subgroupListBuilder.append(subgroupString);
- }
- return subgroupListBuilder.toString();
- }
-
- private String convertAudioCodecConfigToString(BluetoothLeAudioCodecConfigMetadata config) {
- String audioLocation = String.valueOf(config.getAudioLocation());
- String rawMetadata = new String(config.getRawMetadata(), StandardCharsets.UTF_8);
- return new StringBuilder()
- .append(BluetoothBroadcastUtils.PREFIX_BTCC_AUDIO_LOCATION)
- .append(METADATA_START).append(audioLocation).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTCC_RAW_METADATA)
- .append(METADATA_START).append(rawMetadata).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .toString();
- }
-
- private String convertAudioContentToString(BluetoothLeAudioContentMetadata audioContent) {
- String rawMetadata = new String(audioContent.getRawMetadata(), StandardCharsets.UTF_8);
- return new StringBuilder()
- .append(BluetoothBroadcastUtils.PREFIX_BTAC_PROGRAM_INFO)
- .append(METADATA_START).append(audioContent.getProgramInfo()).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTAC_LANGUAGE)
- .append(METADATA_START).append(audioContent.getLanguage()).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTAC_RAW_METADATA)
- .append(METADATA_START).append(rawMetadata).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .toString();
- }
-
- private String convertChannelToString(List<BluetoothLeBroadcastChannel> channelList) {
- StringBuilder channelListBuilder = new StringBuilder();
- String channelString = "";
- for (BluetoothLeBroadcastChannel channel: channelList) {
- String channelAudioCodec = convertAudioCodecConfigToString(channel.getCodecMetadata());
- channelString = new StringBuilder()
- .append(BluetoothBroadcastUtils.PREFIX_BTBC_CHANNEL_INDEX)
- .append(METADATA_START).append(channel.getChannelIndex()).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .append(BluetoothBroadcastUtils.PREFIX_BTBC_CODEC_CONFIG)
- .append(METADATA_START).append(channelAudioCodec).append(METADATA_END)
- .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
- .toString();
- channelListBuilder.append(channelString);
- }
- return channelListBuilder.toString();
- }
-
- /**
- * Example : prefix is with the “BT:”, and end by the Android Version.
- * BT:T:<1>;D:<00:11:22:AA:BB:CC>;AS:<1>;B:…;V:T;;
- *
- * @return BluetoothLeBroadcastMetadata
- */
- public BluetoothLeBroadcastMetadata convertToBroadcastMetadata(String qrCodeString) {
- if (DEBUG) {
- Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata");
- }
-
- Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
- Matcher match = pattern.matcher(qrCodeString);
- if (match.find()) {
- try {
- mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
- mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
- match.group(MATCH_INDEX_DEVICE));
- mSourceAdvertisingSid = Integer.parseInt(
- match.group(MATCH_INDEX_ADVERTISING_SID));
- mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
- mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
- mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
- mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
- mPresentationDelayMicros =
- Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
-
- if (DEBUG) {
- Log.d(TAG, "Converted qrCodeString result: "
- + " ,Type = " + mSourceAddressType
- + " ,Device = " + mSourceDevice
- + " ,AdSid = " + mSourceAdvertisingSid
- + " ,BroadcastId = " + mBroadcastId
- + " ,paSync = " + mPaSyncInterval
- + " ,encrypted = " + mIsEncrypted
- + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
- + " ,delay = " + mPresentationDelayMicros);
- }
-
- mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
-
- return new BluetoothLeBroadcastMetadata.Builder()
- .setSourceDevice(mSourceDevice, mSourceAddressType)
- .setSourceAdvertisingSid(mSourceAdvertisingSid)
- .setBroadcastId(mBroadcastId)
- .setPaSyncInterval(mPaSyncInterval)
- .setEncrypted(mIsEncrypted)
- .setBroadcastCode(mBroadcastCode)
- .setPresentationDelayMicros(mPresentationDelayMicros)
- .addSubgroup(mSubgroup)
- .build();
- } catch (IllegalArgumentException e) {
- Log.d(TAG, "IllegalArgumentException when convert : " + e);
- return null;
- }
- } else {
- if (DEBUG) {
- Log.d(TAG, "The match fail, can not convert it to BluetoothLeBroadcastMetadata.");
- }
- return null;
- }
- }
-
- private BluetoothLeBroadcastSubgroup convertToSubgroup(String subgroupString) {
- if (DEBUG) {
- Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup");
- }
- Pattern pattern = Pattern.compile(PATTERN_BT_SUBGROUP);
- Matcher match = pattern.matcher(subgroupString);
- if (match.find()) {
- mCodecId = Integer.parseInt(match.group(MATCH_INDEX_CODEC_ID));
- mConfigMetadata = convertToConfigMetadata(match.group(MATCH_INDEX_CODEC_CONFIG));
- mContentMetadata = convertToContentMetadata(match.group(MATCH_INDEX_AUDIO_CONTENT));
- mNoChannelPreference = Boolean.valueOf(match.group(MATCH_INDEX_CHANNEL_PREF));
- mChannel =
- convertToChannel(match.group(MATCH_INDEX_BROADCAST_CHANNEL), mConfigMetadata);
-
- BluetoothLeBroadcastSubgroup.Builder subgroupBuilder =
- new BluetoothLeBroadcastSubgroup.Builder();
- subgroupBuilder.setCodecId(mCodecId);
- subgroupBuilder.setCodecSpecificConfig(mConfigMetadata);
- subgroupBuilder.setContentMetadata(mContentMetadata);
-
- for (BluetoothLeBroadcastChannel channel : mChannel) {
- subgroupBuilder.addChannel(channel);
- }
- return subgroupBuilder.build();
- } else {
- if (DEBUG) {
- Log.d(TAG,
- "The match fail, can not convert it to BluetoothLeBroadcastSubgroup.");
- }
- return null;
- }
- }
-
- private BluetoothLeAudioCodecConfigMetadata convertToConfigMetadata(
- String configMetadataString) {
- if (DEBUG) {
- Log.d(TAG,
- "Convert " + configMetadataString + "to BluetoothLeAudioCodecConfigMetadata");
- }
- Pattern pattern = Pattern.compile(PATTERN_REGEX);
- Matcher match = pattern.matcher(configMetadataString);
- ArrayList<String> resultList = new ArrayList<>();
- while (match.find()) {
- resultList.add(match.group(1));
- Log.d(TAG, "Codec Config match : " + match.group(1));
- }
- if (DEBUG) {
- Log.d(TAG, "Converted configMetadataString result: " + resultList.size());
- }
- if (resultList.size() > 0) {
- mAudioLocation = Long.parseLong(resultList.get(LIST_INDEX_AUDIO_LOCATION));
- mCodecConfigMetadata = resultList.get(LIST_INDEX_CODEC_CONFIG_RAW_METADATA).getBytes();
- return new BluetoothLeAudioCodecConfigMetadata.Builder()
- .setAudioLocation(mAudioLocation)
- .build();
- } else {
- if (DEBUG) {
- Log.d(TAG,
- "The match fail, can not convert it to "
- + "BluetoothLeAudioCodecConfigMetadata.");
- }
- return null;
- }
- }
-
- private BluetoothLeAudioContentMetadata convertToContentMetadata(String contentMetadataString) {
- if (DEBUG) {
- Log.d(TAG, "Convert " + contentMetadataString + "to BluetoothLeAudioContentMetadata");
- }
- Pattern pattern = Pattern.compile(PATTERN_REGEX);
- Matcher match = pattern.matcher(contentMetadataString);
- ArrayList<String> resultList = new ArrayList<>();
- while (match.find()) {
- Log.d(TAG, "Audio Content match : " + match.group(1));
- resultList.add(match.group(1));
- }
- if (DEBUG) {
- Log.d(TAG, "Converted contentMetadataString result: " + resultList.size());
- }
- if (resultList.size() > 0) {
- mProgramInfo = resultList.get(LIST_INDEX_PROGRAM_INFO);
- mLanguage = resultList.get(LIST_INDEX_LANGUAGE);
- mAudioContentMetadata =
- resultList.get(LIST_INDEX_AUDIO_CONTENT_RAW_METADATA).getBytes();
-
- /* TODO(b/265253566) : Need to set the default value for language when the user starts
- * the broadcast.
- */
- if (mLanguage.equals("null")) {
- mLanguage = "eng";
- }
-
- return new BluetoothLeAudioContentMetadata.Builder()
- .setProgramInfo(mProgramInfo)
- .setLanguage(mLanguage)
- .build();
- } else {
- if (DEBUG) {
- Log.d(TAG,
- "The match fail, can not convert it to BluetoothLeAudioContentMetadata.");
- }
- return null;
- }
- }
-
- private List<BluetoothLeBroadcastChannel> convertToChannel(String channelString,
- BluetoothLeAudioCodecConfigMetadata configMetadata) {
- if (DEBUG) {
- Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel");
- }
- Pattern pattern = Pattern.compile(PATTERN_BT_CHANNEL);
- Matcher match = pattern.matcher(channelString);
- Map<Integer, BluetoothLeAudioCodecConfigMetadata> channel =
- new HashMap<Integer, BluetoothLeAudioCodecConfigMetadata>();
- while (match.find()) {
- channel.put(Integer.parseInt(match.group(MATCH_INDEX_CHANNEL_INDEX)),
- convertToConfigMetadata(match.group(MATCH_INDEX_CHANNEL_CODEC_CONFIG)));
- }
-
- if (channel.size() > 0) {
- mIsSelected = false;
- ArrayList<BluetoothLeBroadcastChannel> broadcastChannelList = new ArrayList<>();
- for (Map.Entry<Integer, BluetoothLeAudioCodecConfigMetadata> entry :
- channel.entrySet()) {
-
- broadcastChannelList.add(
- new BluetoothLeBroadcastChannel.Builder()
- .setSelected(mIsSelected)
- .setChannelIndex(entry.getKey())
- .setCodecMetadata(entry.getValue())
- .build());
- }
- return broadcastChannelList;
- } else {
- if (DEBUG) {
- Log.d(TAG,
- "The match fail, can not convert it to BluetoothLeBroadcastChannel.");
- }
- return null;
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.kt
new file mode 100644
index 000000000000..870ea8d8b59c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.bluetooth
+
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt.toQrCodeString
+
+@Deprecated("Replace with BluetoothLeBroadcastMetadataExt")
+class LocalBluetoothLeBroadcastMetadata(private val metadata: BluetoothLeBroadcastMetadata?) {
+
+ constructor() : this(null)
+
+ fun convertToQrCodeString(): String = metadata?.toQrCodeString() ?: ""
+
+ fun convertToBroadcastMetadata(qrCodeString: String) =
+ BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)
+} \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index c4f09cecfa1f..f911d35757f6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -111,6 +111,9 @@ public class DreamBackend {
public static final int COMPLICATION_TYPE_SMARTSPACE = 7;
public static final int COMPLICATION_TYPE_MEDIA_ENTRY = 8;
+ private static final int SCREENSAVER_HOME_CONTROLS_ENABLED_DEFAULT = 1;
+ private static final int LOCKSCREEN_SHOW_CONTROLS_DEFAULT = 0;
+
private final Context mContext;
private final IDreamManager mDreamManager;
private final DreamInfoComparator mComparator;
@@ -311,8 +314,14 @@ public class DreamBackend {
/** Gets whether home controls button is enabled on the dream */
private boolean getHomeControlsEnabled() {
- return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED, 1) == 1;
+ return Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+ LOCKSCREEN_SHOW_CONTROLS_DEFAULT) == 1
+ && Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
+ SCREENSAVER_HOME_CONTROLS_ENABLED_DEFAULT) == 1;
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index 765566391ef2..1251b0dc306a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -196,6 +196,9 @@ public class BatteryStatus {
/** Gets the battery level from the intent. */
public static int getBatteryLevel(Intent batteryChangedIntent) {
+ if (batteryChangedIntent == null) {
+ return -1; /*invalid battery level*/
+ }
final int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
final int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
return scale == 0
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 1c82be9c801f..34519c993d27 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -70,13 +70,17 @@ public class PhoneMediaDevice extends MediaDevice {
name = mContext.getString(R.string.media_transfer_wired_usb_device_name);
break;
case TYPE_DOCK:
- case TYPE_HDMI:
- name = mRouteInfo.getName();
+ name = mContext.getString(R.string.media_transfer_dock_speaker_device_name);
break;
case TYPE_BUILTIN_SPEAKER:
- default:
name = mContext.getString(R.string.media_transfer_this_device_name);
break;
+ case TYPE_HDMI:
+ name = mContext.getString(R.string.media_transfer_external_device_name);
+ break;
+ default:
+ name = mContext.getString(R.string.media_transfer_default_device_name);
+ break;
}
return name.toString();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
index e835125b9b81..e6b1cfb440fa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoDao.java
@@ -16,14 +16,13 @@
package com.android.settingslib.mobile.dataservice;
-import java.util.List;
-
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
-import androidx.room.Update;
+
+import java.util.List;
@Dao
public interface SubscriptionInfoDao {
@@ -32,7 +31,9 @@ public interface SubscriptionInfoDao {
void insertSubsInfo(SubscriptionInfoEntity... subscriptionInfo);
@Query("SELECT * FROM " + DataServiceUtils.SubscriptionInfoData.TABLE_NAME + " ORDER BY "
- + DataServiceUtils.SubscriptionInfoData.COLUMN_ID)
+ + " CASE WHEN " + DataServiceUtils.SubscriptionInfoData.COLUMN_SIM_SLOT_INDEX
+ + " >= 0 THEN 1 ELSE 2 END , "
+ + DataServiceUtils.SubscriptionInfoData.COLUMN_SIM_SLOT_INDEX)
LiveData<List<SubscriptionInfoEntity>> queryAvailableSubInfos();
@Query("SELECT * FROM " + DataServiceUtils.SubscriptionInfoData.TABLE_NAME + " WHERE "
@@ -43,7 +44,8 @@ public interface SubscriptionInfoDao {
+ DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_SUBSCRIPTION_ID
+ " = :isActiveSubscription" + " AND "
+ DataServiceUtils.SubscriptionInfoData.COLUMN_IS_SUBSCRIPTION_VISIBLE
- + " = :isSubscriptionVisible")
+ + " = :isSubscriptionVisible" + " ORDER BY "
+ + DataServiceUtils.SubscriptionInfoData.COLUMN_SIM_SLOT_INDEX)
LiveData<List<SubscriptionInfoEntity>> queryActiveSubInfos(
boolean isActiveSubscription, boolean isSubscriptionVisible);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 1d081d7214cc..34d8148f418f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -804,7 +804,7 @@ public class ApplicationsStateRoboTest {
}
@Test
- public void getEntry_validUserId_shouldReturnEntry() {
+ public void getEntry_hasCache_shouldReturnCacheEntry() {
mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
addApp(PKG_1, /* id= */ 1);
@@ -813,10 +813,13 @@ public class ApplicationsStateRoboTest {
}
@Test
- public void getEntry_invalidUserId_shouldReturnNull() {
- mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
- addApp(PKG_1, /* id= */ 1);
+ public void getEntry_hasNoCache_shouldReturnEntry() {
+ mApplicationsState.mEntriesMap.clear();
+ ApplicationInfo appInfo = createApplicationInfo(PKG_1, /* uid= */ 0);
+ mApplicationsState.mApplications.add(appInfo);
+ mApplicationsState.mSystemModules.put(PKG_1, /* value= */ false);
- assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ -1)).isNull();
+ assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ 0).info.packageName)
+ .isEqualTo(PKG_1);
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
index 22ec12d44d6d..2edf403e5c00 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
+import android.provider.Settings;
import org.junit.After;
import org.junit.Before;
@@ -84,6 +85,7 @@ public final class DreamBackendTest {
@Test
public void testComplicationsEnabledByDefault() {
+ setControlsEnabledOnLockscreen(true);
assertThat(mBackend.getComplicationsEnabled()).isTrue();
assertThat(mBackend.getEnabledComplications()).containsExactlyElementsIn(
SUPPORTED_DREAM_COMPLICATIONS_LIST);
@@ -91,6 +93,7 @@ public final class DreamBackendTest {
@Test
public void testEnableComplicationExplicitly() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(true);
assertThat(mBackend.getEnabledComplications()).containsExactlyElementsIn(
SUPPORTED_DREAM_COMPLICATIONS_LIST);
@@ -99,6 +102,7 @@ public final class DreamBackendTest {
@Test
public void testDisableComplications() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(false);
assertThat(mBackend.getEnabledComplications())
.containsExactly(COMPLICATION_TYPE_HOME_CONTROLS);
@@ -107,6 +111,7 @@ public final class DreamBackendTest {
@Test
public void testHomeControlsDisabled_ComplicationsEnabled() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(true);
mBackend.setHomeControlsEnabled(false);
// Home controls should not be enabled, only date and time.
@@ -118,6 +123,7 @@ public final class DreamBackendTest {
@Test
public void testHomeControlsDisabled_ComplicationsDisabled() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(false);
mBackend.setHomeControlsEnabled(false);
assertThat(mBackend.getEnabledComplications()).isEmpty();
@@ -125,9 +131,9 @@ public final class DreamBackendTest {
@Test
public void testHomeControlsEnabled_ComplicationsDisabled() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(false);
mBackend.setHomeControlsEnabled(true);
- // Home controls should not be enabled, only date and time.
final List<Integer> enabledComplications =
Collections.singletonList(COMPLICATION_TYPE_HOME_CONTROLS);
assertThat(mBackend.getEnabledComplications())
@@ -136,9 +142,9 @@ public final class DreamBackendTest {
@Test
public void testHomeControlsEnabled_ComplicationsEnabled() {
+ setControlsEnabledOnLockscreen(true);
mBackend.setComplicationsEnabled(true);
mBackend.setHomeControlsEnabled(true);
- // Home controls should not be enabled, only date and time.
final List<Integer> enabledComplications =
Arrays.asList(
COMPLICATION_TYPE_HOME_CONTROLS,
@@ -148,4 +154,26 @@ public final class DreamBackendTest {
assertThat(mBackend.getEnabledComplications())
.containsExactlyElementsIn(enabledComplications);
}
+
+ @Test
+ public void testHomeControlsEnabled_lockscreenDisabled() {
+ setControlsEnabledOnLockscreen(false);
+ mBackend.setComplicationsEnabled(true);
+ mBackend.setHomeControlsEnabled(true);
+ // Home controls should not be enabled, only date and time.
+ final List<Integer> enabledComplications =
+ Arrays.asList(
+ COMPLICATION_TYPE_DATE,
+ COMPLICATION_TYPE_TIME
+ );
+ assertThat(mBackend.getEnabledComplications())
+ .containsExactlyElementsIn(enabledComplications);
+ }
+
+ private void setControlsEnabledOnLockscreen(boolean enabled) {
+ Settings.Secure.putInt(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+ enabled ? 1 : 0);
+ }
}
diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp
new file mode 100644
index 000000000000..a4558f1bd40b
--- /dev/null
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "SettingsLibUnitTests",
+ test_suites: ["device-tests"],
+
+ srcs: [
+ "src/**/*.kt",
+ ],
+
+ static_libs: [
+ "SettingsLib",
+ "androidx.test.ext.junit",
+ "androidx.test.runner",
+ "truth-prebuilt",
+ ],
+}
diff --git a/packages/SettingsLib/tests/unit/AndroidManifest.xml b/packages/SettingsLib/tests/unit/AndroidManifest.xml
new file mode 100644
index 000000000000..568f9cb2b79e
--- /dev/null
+++ b/packages/SettingsLib/tests/unit/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.settingslib.test">
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="Tests for SettingsLib"
+ android:targetPackage="com.android.settingslib.test">
+ </instrumentation>
+</manifest>
diff --git a/packages/SettingsLib/tests/unit/OWNERS b/packages/SettingsLib/tests/unit/OWNERS
new file mode 100644
index 000000000000..66559252048b
--- /dev/null
+++ b/packages/SettingsLib/tests/unit/OWNERS
@@ -0,0 +1,2 @@
+# We do not guard tests - everyone is welcomed to contribute to tests.
+per-file *.kt=*
diff --git a/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
new file mode 100644
index 000000000000..27d7078774d5
--- /dev/null
+++ b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothLeAudioCodecConfigMetadata
+import android.bluetooth.BluetoothLeAudioContentMetadata
+import android.bluetooth.BluetoothLeBroadcastChannel
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.bluetooth.BluetoothLeBroadcastSubgroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt.toQrCodeString
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class BluetoothLeBroadcastMetadataExtTest {
+
+ @Test
+ fun toQrCodeString() {
+ val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(0x6)
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(true)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(true)
+ setChannelIndex(1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ }.build()
+
+ val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
+ setSourceAdvertisingSid(1)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
+ setEncrypted(true)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
+ addSubgroup(subgroup)
+ }.build()
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ assertThat(qrCodeString).isEqualTo(QR_CODE_STRING)
+ }
+
+ @Test
+ fun toQrCodeString_NoChannelSelected() {
+ val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(0x6)
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ }.build()
+
+ val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
+ setSourceAdvertisingSid(1)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
+ setEncrypted(true)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
+ addSubgroup(subgroup)
+ }.build()
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ val parsedMetadata =
+ BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
+
+ assertThat(parsedMetadata).isNotNull()
+ assertThat(parsedMetadata.subgroups).isNotNull()
+ assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
+ assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isFalse()
+ // Input order does not matter due to parsing through bisMask
+ assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
+ assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isFalse()
+ }
+
+ @Test
+ fun toQrCodeString_OneChannelSelected() {
+ val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(0x6)
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(true)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ }.build()
+
+ val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
+ setSourceAdvertisingSid(1)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
+ setEncrypted(true)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
+ addSubgroup(subgroup)
+ }.build()
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ val parsedMetadata =
+ BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
+
+ assertThat(parsedMetadata).isNotNull()
+ assertThat(parsedMetadata.subgroups).isNotNull()
+ assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
+ // Only selected channel can be recovered
+ assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isTrue()
+ assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
+ assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isTrue()
+ }
+
+ @Test
+ fun decodeAndEncodeAgain_sameString() {
+ val metadata = BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(QR_CODE_STRING)!!
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ assertThat(qrCodeString).isEqualTo(QR_CODE_STRING)
+ }
+
+ private companion object {
+ const val TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"
+
+ val Device: BluetoothDevice =
+ BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS,
+ BluetoothDevice.ADDRESS_TYPE_RANDOM)
+
+ const val QR_CODE_STRING =
+ "BT:R:65536;T:1;D:00-A1-A1-A1-A1-A1;AS:1;B:123456;BN:VGVzdA==;" +
+ "PM:BgNwVGVzdA==;SI:160;C:VGVzdENvZGU=;SG:BS:3,BM:3,AC:BQNUZXN0BARlbmc=;" +
+ "VN:U;;"
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b661ba485e73..476c820a79a7 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -176,6 +176,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
+ <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
<!-- Assist -->
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index bdd941d537bf..01e6bf00a664 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -1,6 +1,22 @@
{
- // Looking for unit test presubmit configuration?
- // This currently lives in ATP config apct/system_ui/unit_test
+ // Curious where your @Scenario tests will run?
+ //
+ // @Ignore: Will not run in any configuration
+ //
+ // @FlakyTest: Tests that don't block pre/postsubmit but are staged to run known failures
+ //
+ // @Postsubmit: Runs in platinum suite and blocks droidfood in postsubmit
+ //
+ // @PlatinumTest: As of May, 2023, running in postsubmit. Set to run in presubmit as part of
+ // v2/android-platinum/suite-test-mapping-platinum-sysui
+ // Please DO NOT annotate new or old tests with @PlatinumTest annotation without discussing
+ // with mdb:android-platinum
+ //
+ // As of May, 2023, If you don't use @Postsubmit, your new test will immediately
+ // block presubmit, which is probably NOT what you want. This will change effectively once
+ // we move to @PlatinumTest annotation.
+
+ // v2/sysui/test-mapping-presubmit-sysui_cloud-tf
"presubmit-sysui": [
{
"name": "PlatformScenarioTests",
@@ -23,6 +39,7 @@
]
}
],
+ // v2/android-virtual-infra/test_mapping/presubmit-avd
"presubmit": [
{
"name": "SystemUIGoogleTests",
@@ -75,45 +92,26 @@
]
}
],
-
- // Curious where your @Scenario tests will run?
- //
- // @Ignore: nowhere
- // @FlakyTest: in staged-postsubmit, but not blocking postsubmit or
- // presubmit
- // @Postsubmit: in postsubmit and staged-postsubmit, but not presubmit
- // none of the above: in presubmit, postsubmit, and staged-postsubmit
- //
- // Ideally, please annotate new tests with @FlakyTest, then with @Postsubmit
- // once they're ready for postsubmit as they will immediately block go/android-platinum,
- // then with neither once they're ready for presubmit.
- //
- // If you don't use @Postsubmit, your new test will immediately
- // block presubmit, which is probably not what you want!
- "sysui-platinum-postsubmit": [
+ "auto-end-to-end-postsubmit": [
{
- "name": "PlatformScenarioTests",
- "options": [
- {
- "include-filter": "android.platform.test.scenario.sysui"
- },
- {
- "include-annotation": "android.platform.test.scenario.annotation.Scenario"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
+ "name": "AndroidAutomotiveHomeTests",
+ "options" : [
{
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
+ "include-filter": "android.platform.tests.HomeTest"
+ }
+ ]
+ },
+ {
+ "name": "AndroidAutomotiveNotificationsTests",
+ "options" : [
{
- "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ "include-filter": "android.platform.tests.NotificationTest"
}
]
}
],
- "sysui-staged-platinum-postsubmit": [
- {
+ "silver-sysui": [
+ {
"name": "PlatformScenarioTests",
"options": [
{
@@ -124,45 +122,14 @@
},
{
"exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
- ],
- "ironwood-postsubmit": [
- {
- "name": "PlatformScenarioTests",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
},
{
- "include-filter": "android.platform.test.scenario.sysui"
+ "exclude-annotation": "android.platform.test.annotations.PlatinumTest"
},
{
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
}
- ],
- "auto-end-to-end-postsubmit": [
- {
- "name": "AndroidAutomotiveHomeTests",
- "options" : [
- {
- "include-filter": "android.platform.tests.HomeTest"
- }
- ]
- },
- {
- "name": "AndroidAutomotiveNotificationsTests",
- "options" : [
- {
- "include-filter": "android.platform.tests.NotificationTest"
- }
- ]
- }
]
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
index 1ae3213639e1..eff6cb45309b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
@@ -9,7 +9,7 @@
<string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
<string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
<string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
- <string name="lockscreen_label" msgid="648347953557887087">"Zaključan zaslon"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaključani zaslon"</string>
<string name="quick_settings_label" msgid="2999117381487601865">"Brze postavke"</string>
<string name="notifications_label" msgid="6829741046963013567">"Obavijesti"</string>
<string name="screenshot_label" msgid="863978141223970162">"Snimka zaslona"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
index 40c961c59b1b..ac6b5c3f8339 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙選單"</string>
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙工具選單"</string>
<string name="accessibility_menu_intro" msgid="3164193281544042394">"無障礙工具選單是螢幕上的大型選單,可用來操控裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕畫面,以及執行其他功能。"</string>
<string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
<string name="assistant_utterance" msgid="65509599221141377">"Google 助理"</string>
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Easings.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Easings.kt
new file mode 100644
index 000000000000..4fe9f89830f6
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Easings.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation
+
+import androidx.compose.animation.core.Easing
+import androidx.core.animation.Interpolator
+import com.android.app.animation.InterpolatorsAndroidX
+
+/**
+ * Compose-compatible definition of Android motion eases, see
+ * https://carbon.googleplex.com/android-motion/pages/easing
+ */
+object Easings {
+
+ /** The standard interpolator that should be used on every normal animation */
+ val Standard = fromInterpolator(InterpolatorsAndroidX.STANDARD)
+
+ /**
+ * The standard accelerating interpolator that should be used on every regular movement of
+ * content that is disappearing e.g. when moving off screen.
+ */
+ val StandardAccelerate = fromInterpolator(InterpolatorsAndroidX.STANDARD_ACCELERATE)
+
+ /**
+ * The standard decelerating interpolator that should be used on every regular movement of
+ * content that is appearing e.g. when coming from off screen.
+ */
+ val StandardDecelerate = fromInterpolator(InterpolatorsAndroidX.STANDARD_DECELERATE)
+
+ /** The default emphasized interpolator. Used for hero / emphasized movement of content. */
+ val Emphasized = fromInterpolator(InterpolatorsAndroidX.EMPHASIZED)
+
+ /**
+ * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that
+ * is disappearing e.g. when moving off screen.
+ */
+ val EmphasizedAccelerate = fromInterpolator(InterpolatorsAndroidX.EMPHASIZED_ACCELERATE)
+
+ /**
+ * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that
+ * is appearing e.g. when coming from off screen
+ */
+ val EmphasizedDecelerate = fromInterpolator(InterpolatorsAndroidX.EMPHASIZED_DECELERATE)
+
+ /** The linear interpolator. */
+ val Linear = fromInterpolator(InterpolatorsAndroidX.LINEAR)
+
+ /** The default legacy interpolator as defined in Material 1. Also known as FAST_OUT_SLOW_IN. */
+ val Legacy = fromInterpolator(InterpolatorsAndroidX.LEGACY)
+
+ /**
+ * The default legacy accelerating interpolator as defined in Material 1. Also known as
+ * FAST_OUT_LINEAR_IN.
+ */
+ val LegacyAccelerate = fromInterpolator(InterpolatorsAndroidX.LEGACY_ACCELERATE)
+
+ /**
+ * T The default legacy decelerating interpolator as defined in Material 1. Also known as
+ * LINEAR_OUT_SLOW_IN.
+ */
+ val LegacyDecelerate = fromInterpolator(InterpolatorsAndroidX.LEGACY_DECELERATE)
+
+ private fun fromInterpolator(source: Interpolator) = Easing { x -> source.getInterpolation(x) }
+}
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
index 954bad56bcc2..d3643747ad91 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.scene.ui.composable
+import android.content.Context
import com.android.systemui.bouncer.ui.composable.BouncerScene
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.dagger.SysUISingleton
@@ -28,6 +29,7 @@ import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ui.composable.ShadeScene
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import com.android.systemui.statusbar.phone.SystemUIDialog
import dagger.Module
import dagger.Provides
import javax.inject.Named
@@ -57,6 +59,7 @@ object SceneModule {
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun bouncerScene(
+ @Application context: Context,
viewModelFactory: BouncerViewModel.Factory,
): BouncerScene {
return BouncerScene(
@@ -64,6 +67,7 @@ object SceneModule {
viewModelFactory.create(
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
),
+ dialogFactory = { SystemUIDialog(context) },
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index 3c74ef5adfeb..240bace21a1c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -14,9 +14,16 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalMaterial3Api::class)
+
package com.android.systemui.bouncer.ui.composable
+import android.app.AlertDialog
+import android.app.Dialog
+import android.content.DialogInterface
import androidx.compose.animation.Crossfade
+import androidx.compose.animation.core.snap
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -26,15 +33,20 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import com.android.systemui.R
import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
@@ -51,6 +63,7 @@ import kotlinx.coroutines.flow.asStateFlow
/** The bouncer scene displays authentication challenges like PIN, password, or pattern. */
class BouncerScene(
private val viewModel: BouncerViewModel,
+ private val dialogFactory: () -> AlertDialog,
) : ComposableScene {
override val key = SceneKey.Bouncer
@@ -68,16 +81,19 @@ class BouncerScene(
override fun Content(
containerName: String,
modifier: Modifier,
- ) = BouncerScene(viewModel, modifier)
+ ) = BouncerScene(viewModel, dialogFactory, modifier)
}
@Composable
private fun BouncerScene(
viewModel: BouncerViewModel,
+ dialogFactory: () -> AlertDialog,
modifier: Modifier = Modifier,
) {
- val message: String by viewModel.message.collectAsState()
+ val message: BouncerViewModel.MessageViewModel by viewModel.message.collectAsState()
val authMethodViewModel: AuthMethodBouncerViewModel? by viewModel.authMethod.collectAsState()
+ val dialogMessage: String? by viewModel.throttlingDialogMessage.collectAsState()
+ var dialog: Dialog? by remember { mutableStateOf(null) }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -88,9 +104,10 @@ private fun BouncerScene(
Crossfade(
targetState = message,
label = "Bouncer message",
- ) {
+ animationSpec = if (message.isUpdateAnimated) tween() else snap(),
+ ) { message ->
Text(
- text = it,
+ text = message.text,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge,
)
@@ -132,5 +149,26 @@ private fun BouncerScene(
style = MaterialTheme.typography.bodyMedium,
)
}
+
+ if (dialogMessage != null) {
+ if (dialog == null) {
+ dialog =
+ dialogFactory().apply {
+ setMessage(dialogMessage)
+ setButton(
+ DialogInterface.BUTTON_NEUTRAL,
+ context.getString(R.string.ok),
+ ) { _, _ ->
+ viewModel.onThrottlingDialogDismissed()
+ }
+ setCancelable(false)
+ setCanceledOnTouchOutside(false)
+ show()
+ }
+ }
+ } else {
+ dialog?.dismiss()
+ dialog = null
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
index 4e85621e9e23..7545ff464bab 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
@@ -53,6 +53,8 @@ internal fun PasswordBouncer(
) {
val focusRequester = remember { FocusRequester() }
val password: String by viewModel.password.collectAsState()
+ val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
+ val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
LaunchedEffect(Unit) {
// When the UI comes up, request focus on the TextField to bring up the software keyboard.
@@ -61,6 +63,13 @@ internal fun PasswordBouncer(
viewModel.onShown()
}
+ LaunchedEffect(animateFailure) {
+ if (animateFailure) {
+ // We don't currently have a failure animation for password, just consume it:
+ viewModel.onFailureAnimationShown()
+ }
+ }
+
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier,
@@ -71,6 +80,7 @@ internal fun PasswordBouncer(
TextField(
value = password,
onValueChange = viewModel::onPasswordInputChanged,
+ enabled = isInputEnabled,
visualTransformation = PasswordVisualTransformation(),
singleLine = true,
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
index 3afd33f4c90c..b3d2e350ed50 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
@@ -18,6 +18,7 @@ package com.android.systemui.bouncer.ui.composable
import android.view.HapticFeedbackConstants
import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.gestures.detectDragGestures
@@ -41,12 +42,15 @@ import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.integerResource
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
+import com.android.compose.animation.Easings
import com.android.internal.R
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternDotViewModel
+import com.android.systemui.compose.modifiers.thenIf
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sqrt
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
/**
@@ -66,9 +70,9 @@ internal fun PatternBouncer(
val rowCount = viewModel.rowCount
val dotColor = MaterialTheme.colorScheme.secondary
- val dotRadius = with(LocalDensity.current) { 8.dp.toPx() }
+ val dotRadius = with(LocalDensity.current) { (DOT_DIAMETER_DP / 2).dp.toPx() }
val lineColor = MaterialTheme.colorScheme.primary
- val lineStrokeWidth = dotRadius * 2 + with(LocalDensity.current) { 4.dp.toPx() }
+ val lineStrokeWidth = with(LocalDensity.current) { LINE_STROKE_WIDTH_DP.dp.toPx() }
var containerSize: IntSize by remember { mutableStateOf(IntSize(0, 0)) }
val horizontalSpacing = containerSize.width / colCount
@@ -82,6 +86,9 @@ internal fun PatternBouncer(
val currentDot: PatternDotViewModel? by viewModel.currentDot.collectAsState()
// The dots selected so far, if the user is currently dragging.
val selectedDots: List<PatternDotViewModel> by viewModel.selectedDots.collectAsState()
+ val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
+ val isAnimationEnabled: Boolean by viewModel.isPatternVisible.collectAsState()
+ val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
// Map of animatables for the scale of each dot, keyed by dot.
val dotScalingAnimatables = remember(dots) { dots.associateWith { Animatable(1f) } }
@@ -96,19 +103,46 @@ internal fun PatternBouncer(
val view = LocalView.current
// When the current dot is changed, we need to update our animations.
- LaunchedEffect(currentDot) {
- view.performHapticFeedback(
- HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING,
- )
+ LaunchedEffect(currentDot, isAnimationEnabled) {
+ // Perform haptic feedback, but only if the current dot is not null, so we don't perform it
+ // when the UI first shows up or when the user lifts their pointer/finger.
+ if (currentDot != null) {
+ view.performHapticFeedback(
+ HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING,
+ )
+ }
+
+ if (!isAnimationEnabled) {
+ return@LaunchedEffect
+ }
- // Make sure that the current dot is scaled up while the other dots are scaled back down.
+ // Make sure that the current dot is scaled up while the other dots are scaled back
+ // down.
dotScalingAnimatables.entries.forEach { (dot, animatable) ->
val isSelected = dot == currentDot
- launch {
- animatable.animateTo(if (isSelected) 2f else 1f)
+ // Launch using the longer-lived scope because we want these animations to proceed to
+ // completion even if the LaunchedEffect is canceled because its key objects have
+ // changed.
+ scope.launch {
if (isSelected) {
- animatable.animateTo(1f)
+ animatable.animateTo(
+ targetValue = (SELECTED_DOT_DIAMETER_DP / DOT_DIAMETER_DP.toFloat()),
+ animationSpec =
+ tween(
+ durationMillis = SELECTED_DOT_REACTION_ANIMATION_DURATION_MS,
+ easing = Easings.StandardAccelerate,
+ ),
+ )
+ } else {
+ animatable.animateTo(
+ targetValue = 1f,
+ animationSpec =
+ tween(
+ durationMillis = SELECTED_DOT_RETRACT_ANIMATION_DURATION_MS,
+ easing = Easings.StandardDecelerate,
+ ),
+ )
}
}
}
@@ -116,14 +150,18 @@ internal fun PatternBouncer(
selectedDots.forEach { dot ->
lineFadeOutAnimatables[dot]?.let { line ->
if (!line.isRunning) {
+ // Launch using the longer-lived scope because we want these animations to
+ // proceed to completion even if the LaunchedEffect is canceled because its key
+ // objects have changed.
scope.launch {
if (dot == currentDot) {
- // Reset the fade-out animation for the current dot. When the current
- // dot is switched, this entire code block runs again for the newly
- // selected dot.
+ // Reset the fade-out animation for the current dot. When the
+ // current dot is switched, this entire code block runs again for
+ // the newly selected dot.
line.snapTo(1f)
} else {
- // For all non-current dots, make sure that the lines are fading out.
+ // For all non-current dots, make sure that the lines are fading
+ // out.
line.animateTo(
targetValue = 0f,
animationSpec =
@@ -139,6 +177,17 @@ internal fun PatternBouncer(
}
}
+ // Show the failure animation if the user entered the wrong input.
+ LaunchedEffect(animateFailure) {
+ if (animateFailure) {
+ showFailureAnimation(
+ dots = dots,
+ scalingAnimatables = dotScalingAnimatables,
+ )
+ viewModel.onFailureAnimationShown()
+ }
+ }
+
// This is the position of the input pointer.
var inputPosition: Offset? by remember { mutableStateOf(null) }
@@ -148,27 +197,34 @@ internal fun PatternBouncer(
// when it leaves the bounds of the dot grid.
.clipToBounds()
.onSizeChanged { containerSize = it }
- .pointerInput(Unit) {
- detectDragGestures(
- onDragStart = { start ->
- inputPosition = start
- viewModel.onDragStart()
- },
- onDragEnd = {
- inputPosition = null
- lineFadeOutAnimatables.values.forEach { animatable ->
- scope.launch { animatable.animateTo(1f) }
- }
- viewModel.onDragEnd()
- },
- ) { change, _ ->
- inputPosition = change.position
- viewModel.onDrag(
- xPx = change.position.x,
- yPx = change.position.y,
- containerSizePx = containerSize.width,
- verticalOffsetPx = verticalOffset,
- )
+ .thenIf(isInputEnabled) {
+ Modifier.pointerInput(Unit) {
+ detectDragGestures(
+ onDragStart = { start ->
+ inputPosition = start
+ viewModel.onDragStart()
+ },
+ onDragEnd = {
+ inputPosition = null
+ if (isAnimationEnabled) {
+ lineFadeOutAnimatables.values.forEach { animatable ->
+ // Launch using the longer-lived scope because we want these
+ // animations to proceed to completion even if the surrounding
+ // scope is canceled.
+ scope.launch { animatable.animateTo(1f) }
+ }
+ }
+ viewModel.onDragEnd()
+ },
+ ) { change, _ ->
+ inputPosition = change.position
+ viewModel.onDrag(
+ xPx = change.position.x,
+ yPx = change.position.y,
+ containerSizePx = containerSize.width,
+ verticalOffsetPx = verticalOffset,
+ )
+ }
}
}
) {
@@ -247,3 +303,62 @@ private fun lineAlpha(gridSpacing: Float, lineLength: Float = gridSpacing): Floa
// farther the user input pointer goes from the line, the more opaque the line gets.
return ((lineLength / gridSpacing - 0.3f) * 4f).coerceIn(0f, 1f)
}
+
+private suspend fun showFailureAnimation(
+ dots: List<PatternDotViewModel>,
+ scalingAnimatables: Map<PatternDotViewModel, Animatable<Float, AnimationVector1D>>,
+) {
+ val dotsByRow =
+ buildList<MutableList<PatternDotViewModel>> {
+ dots.forEach { dot ->
+ val rowIndex = dot.y
+ while (size <= rowIndex) {
+ add(mutableListOf())
+ }
+ get(rowIndex).add(dot)
+ }
+ }
+
+ coroutineScope {
+ dotsByRow.forEachIndexed { rowIndex, rowDots ->
+ rowDots.forEach { dot ->
+ scalingAnimatables[dot]?.let { dotScaleAnimatable ->
+ launch {
+ dotScaleAnimatable.animateTo(
+ targetValue =
+ FAILURE_ANIMATION_DOT_DIAMETER_DP / DOT_DIAMETER_DP.toFloat(),
+ animationSpec =
+ tween(
+ durationMillis =
+ FAILURE_ANIMATION_DOT_SHRINK_ANIMATION_DURATION_MS,
+ delayMillis =
+ rowIndex * FAILURE_ANIMATION_DOT_SHRINK_STAGGER_DELAY_MS,
+ easing = Easings.Linear,
+ ),
+ )
+
+ dotScaleAnimatable.animateTo(
+ targetValue = 1f,
+ animationSpec =
+ tween(
+ durationMillis =
+ FAILURE_ANIMATION_DOT_REVERT_ANIMATION_DURATION,
+ easing = Easings.Standard,
+ ),
+ )
+ }
+ }
+ }
+ }
+ }
+}
+
+private const val DOT_DIAMETER_DP = 16
+private const val SELECTED_DOT_DIAMETER_DP = 24
+private const val SELECTED_DOT_REACTION_ANIMATION_DURATION_MS = 83
+private const val SELECTED_DOT_RETRACT_ANIMATION_DURATION_MS = 750
+private const val LINE_STROKE_WIDTH_DP = 16
+private const val FAILURE_ANIMATION_DOT_DIAMETER_DP = 13
+private const val FAILURE_ANIMATION_DOT_SHRINK_ANIMATION_DURATION_MS = 50
+private const val FAILURE_ANIMATION_DOT_SHRINK_STAGGER_DELAY_MS = 33
+private const val FAILURE_ANIMATION_DOT_REVERT_ANIMATION_DURATION = 617
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
index 9c210c225ab3..f80143499928 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -18,20 +18,20 @@
package com.android.systemui.bouncer.ui.composable
-import androidx.compose.animation.AnimatedVisibility
+import android.view.HapticFeedbackConstants
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.animateColorAsState
-import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.animation.core.Transition
+import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateDpAsState
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.scaleIn
-import androidx.compose.animation.scaleOut
-import androidx.compose.animation.slideInHorizontally
-import androidx.compose.animation.slideOutHorizontally
-import androidx.compose.foundation.background
+import androidx.compose.animation.core.keyframes
+import androidx.compose.animation.core.snap
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
+import androidx.compose.foundation.Canvas
import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -39,31 +39,45 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.runtime.snapshotFlow
+import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import com.android.compose.animation.Easings
import com.android.compose.grid.VerticalGrid
import com.android.systemui.R
+import com.android.systemui.bouncer.ui.viewmodel.EnteredKey
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
-import kotlin.math.max
+import com.android.systemui.compose.modifiers.thenIf
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.DurationUnit
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
@Composable
internal fun PinBouncer(
@@ -73,37 +87,22 @@ internal fun PinBouncer(
// Report that the UI is shown to let the view-model run some logic.
LaunchedEffect(Unit) { viewModel.onShown() }
- // The length of the PIN input received so far, so we know how many dots to render.
- val pinLength: Pair<Int, Int> by viewModel.pinLengths.collectAsState()
+ val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
+ val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
+
+ // Show the failure animation if the user entered the wrong input.
+ LaunchedEffect(animateFailure) {
+ if (animateFailure) {
+ showFailureAnimation()
+ viewModel.onFailureAnimationShown()
+ }
+ }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier,
) {
- Row(
- horizontalArrangement = Arrangement.spacedBy(12.dp),
- modifier = Modifier.heightIn(min = 16.dp).animateContentSize(),
- ) {
- // TODO(b/281871687): add support for dot shapes.
- val (previousPinLength, currentPinLength) = pinLength
- val dotCount = max(previousPinLength, currentPinLength) + 1
- repeat(dotCount) { index ->
- AnimatedVisibility(
- visible = index < currentPinLength,
- enter = fadeIn() + scaleIn() + slideInHorizontally(),
- exit = fadeOut() + scaleOut() + slideOutHorizontally(),
- ) {
- Box(
- modifier =
- Modifier.size(16.dp)
- .background(
- MaterialTheme.colorScheme.onSurfaceVariant,
- CircleShape,
- )
- )
- }
- }
- }
+ PinInputDisplay(viewModel)
Spacer(Modifier.height(100.dp))
@@ -116,6 +115,7 @@ internal fun PinBouncer(
val digit = index + 1
PinButton(
onClicked = { viewModel.onPinButtonClicked(digit) },
+ isEnabled = isInputEnabled,
) { contentColor ->
PinDigit(digit, contentColor)
}
@@ -124,7 +124,8 @@ internal fun PinBouncer(
PinButton(
onClicked = { viewModel.onBackspaceButtonClicked() },
onLongPressed = { viewModel.onBackspaceButtonLongPressed() },
- isHighlighted = true,
+ isEnabled = isInputEnabled,
+ isIconButton = true,
) { contentColor ->
PinIcon(
Icon.Resource(
@@ -138,13 +139,15 @@ internal fun PinBouncer(
PinButton(
onClicked = { viewModel.onPinButtonClicked(0) },
+ isEnabled = isInputEnabled,
) { contentColor ->
PinDigit(0, contentColor)
}
PinButton(
onClicked = { viewModel.onAuthenticateButtonClicked() },
- isHighlighted = true,
+ isEnabled = isInputEnabled,
+ isIconButton = true,
) { contentColor ->
PinIcon(
Icon.Resource(
@@ -160,6 +163,148 @@ internal fun PinBouncer(
}
@Composable
+private fun PinInputDisplay(viewModel: PinBouncerViewModel) {
+ val currentPinEntries: List<EnteredKey> by viewModel.pinEntries.collectAsState()
+
+ // visiblePinEntries keeps pins removed from currentPinEntries in the composition until their
+ // disappear-animation completed. The list is sorted by the natural ordering of EnteredKey,
+ // which is guaranteed to produce the original edit order, since the model only modifies entries
+ // at the end.
+ val visiblePinEntries = remember { SnapshotStateList<EnteredKey>() }
+ currentPinEntries.forEach {
+ val index = visiblePinEntries.binarySearch(it)
+ if (index < 0) {
+ val insertionPoint = -(index + 1)
+ visiblePinEntries.add(insertionPoint, it)
+ }
+ }
+
+ Row(
+ modifier =
+ Modifier.heightIn(min = entryShapeSize)
+ // Pins overflowing horizontally should still be shown as scrolling.
+ .wrapContentSize(unbounded = true),
+ ) {
+ visiblePinEntries.forEachIndexed { index, entry ->
+ key(entry) {
+ val visibility = remember {
+ MutableTransitionState<EntryVisibility>(EntryVisibility.Hidden)
+ }
+ visibility.targetState =
+ when {
+ currentPinEntries.isEmpty() && visiblePinEntries.size > 1 ->
+ EntryVisibility.BulkHidden(index, visiblePinEntries.size)
+ currentPinEntries.contains(entry) -> EntryVisibility.Shown
+ else -> EntryVisibility.Hidden
+ }
+
+ ObscuredInputEntry(updateTransition(visibility, label = "Pin Entry $entry"))
+
+ LaunchedEffect(entry) {
+ // Remove entry from visiblePinEntries once the hide transition completed.
+ snapshotFlow {
+ visibility.currentState == visibility.targetState &&
+ visibility.targetState != EntryVisibility.Shown
+ }
+ .collect { isRemoved ->
+ if (isRemoved) {
+ visiblePinEntries.remove(entry)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+private sealed class EntryVisibility {
+ object Shown : EntryVisibility()
+
+ object Hidden : EntryVisibility()
+
+ /**
+ * Same as [Hidden], but applies when multiple entries are hidden simultaneously, without
+ * collapsing during the hide.
+ */
+ data class BulkHidden(val staggerIndex: Int, val totalEntryCount: Int) : EntryVisibility()
+}
+
+@Composable
+private fun ObscuredInputEntry(transition: Transition<EntryVisibility>) {
+ // spec: http://shortn/_DEhE3Xl2bi
+ val shapePadding = 6.dp
+ val shapeOvershootSize = 22.dp
+ val dismissStaggerDelayMs = 33
+ val dismissDurationMs = 450
+ val expansionDurationMs = 250
+ val shapeExpandDurationMs = 83
+ val shapeRetractDurationMs = 167
+ val shapeCollapseDurationMs = 200
+
+ val animatedEntryWidth by
+ transition.animateDp(
+ transitionSpec = {
+ when (val target = targetState) {
+ is EntryVisibility.BulkHidden ->
+ // only collapse horizontal space once all entries are removed
+ snap(dismissDurationMs + dismissStaggerDelayMs * target.totalEntryCount)
+ else -> tween(expansionDurationMs, easing = Easings.Standard)
+ }
+ },
+ label = "entry space"
+ ) { state ->
+ if (state == EntryVisibility.Shown) entryShapeSize + (shapePadding * 2) else 0.dp
+ }
+
+ val animatedShapeSize by
+ transition.animateDp(
+ transitionSpec = {
+ when {
+ EntryVisibility.Hidden isTransitioningTo EntryVisibility.Shown ->
+ keyframes {
+ durationMillis = shapeExpandDurationMs + shapeRetractDurationMs
+ 0.dp at 0 with Easings.Linear
+ shapeOvershootSize at shapeExpandDurationMs with Easings.Legacy
+ }
+ targetState is EntryVisibility.BulkHidden -> {
+ val target = targetState as EntryVisibility.BulkHidden
+ tween(
+ dismissDurationMs,
+ delayMillis = target.staggerIndex * dismissStaggerDelayMs,
+ easing = Easings.Legacy,
+ )
+ }
+ else -> tween(shapeCollapseDurationMs, easing = Easings.StandardDecelerate)
+ }
+ },
+ label = "shape size"
+ ) { state ->
+ when (state) {
+ EntryVisibility.Shown -> entryShapeSize
+ else -> 0.dp
+ }
+ }
+
+ val dotColor = MaterialTheme.colorScheme.onSurfaceVariant
+ Layout(
+ content = {
+ // TODO(b/282730134): add support for dot shapes.
+ Canvas(Modifier) { drawCircle(dotColor) }
+ }
+ ) { measurables, _ ->
+ val shapeSizePx = animatedShapeSize.roundToPx()
+ val placeable = measurables.single().measure(Constraints.fixed(shapeSizePx, shapeSizePx))
+
+ layout(animatedEntryWidth.roundToPx(), entryShapeSize.roundToPx()) {
+ placeable.place(
+ ((animatedEntryWidth - animatedShapeSize) / 2f).roundToPx(),
+ ((entryShapeSize - animatedShapeSize) / 2f).roundToPx()
+ )
+ }
+ }
+}
+
+@Composable
private fun PinDigit(
digit: Int,
contentColor: Color,
@@ -187,61 +332,109 @@ private fun PinIcon(
@Composable
private fun PinButton(
onClicked: () -> Unit,
+ isEnabled: Boolean,
modifier: Modifier = Modifier,
onLongPressed: (() -> Unit)? = null,
- isHighlighted: Boolean = false,
+ isIconButton: Boolean = false,
content: @Composable (contentColor: Color) -> Unit,
) {
var isPressed: Boolean by remember { mutableStateOf(false) }
+
+ val view = LocalView.current
+ LaunchedEffect(isPressed) {
+ if (isPressed) {
+ view.performHapticFeedback(
+ HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING,
+ )
+ }
+ }
+
+ // Pin button animation specification is asymmetric: fast animation to the pressed state, and a
+ // slow animation upon release. Note that isPressed is guaranteed to be true for at least the
+ // press animation duration (see below in detectTapGestures).
+ val animEasing = if (isPressed) pinButtonPressedEasing else pinButtonReleasedEasing
+ val animDurationMillis =
+ (if (isPressed) pinButtonPressedDuration else pinButtonReleasedDuration).toInt(
+ DurationUnit.MILLISECONDS
+ )
+
val cornerRadius: Dp by
animateDpAsState(
- if (isPressed) 24.dp else PinButtonSize / 2,
+ if (isPressed) 24.dp else pinButtonSize / 2,
label = "PinButton round corners",
+ animationSpec = tween(animDurationMillis, easing = animEasing)
)
+ val colorAnimationSpec: AnimationSpec<Color> = tween(animDurationMillis, easing = animEasing)
val containerColor: Color by
animateColorAsState(
when {
- isPressed -> MaterialTheme.colorScheme.primaryContainer
- isHighlighted -> MaterialTheme.colorScheme.secondaryContainer
- else -> MaterialTheme.colorScheme.surface
+ isPressed -> MaterialTheme.colorScheme.primary
+ isIconButton -> MaterialTheme.colorScheme.secondaryContainer
+ else -> MaterialTheme.colorScheme.surfaceVariant
},
label = "Pin button container color",
+ animationSpec = colorAnimationSpec
)
val contentColor: Color by
animateColorAsState(
when {
- isPressed -> MaterialTheme.colorScheme.onPrimaryContainer
- isHighlighted -> MaterialTheme.colorScheme.onSecondaryContainer
- else -> MaterialTheme.colorScheme.onSurface
+ isPressed -> MaterialTheme.colorScheme.onPrimary
+ isIconButton -> MaterialTheme.colorScheme.onSecondaryContainer
+ else -> MaterialTheme.colorScheme.onSurfaceVariant
},
label = "Pin button container color",
+ animationSpec = colorAnimationSpec
)
+ val scope = rememberCoroutineScope()
+
Box(
contentAlignment = Alignment.Center,
modifier =
modifier
- .size(PinButtonSize)
+ .size(pinButtonSize)
.drawBehind {
drawRoundRect(
color = containerColor,
cornerRadius = CornerRadius(cornerRadius.toPx()),
)
}
- .pointerInput(Unit) {
- detectTapGestures(
- onPress = {
- isPressed = true
- tryAwaitRelease()
- isPressed = false
- },
- onTap = { onClicked() },
- onLongPress = onLongPressed?.let { { onLongPressed() } },
- )
+ .thenIf(isEnabled) {
+ Modifier.pointerInput(Unit) {
+ detectTapGestures(
+ onPress = {
+ scope.launch {
+ isPressed = true
+ val minDuration = async {
+ delay(pinButtonPressedDuration + pinButtonHoldTime)
+ }
+ tryAwaitRelease()
+ minDuration.await()
+ isPressed = false
+ }
+ },
+ onTap = { onClicked() },
+ onLongPress = onLongPressed?.let { { onLongPressed() } },
+ )
+ }
},
) {
content(contentColor)
}
}
-private val PinButtonSize = 84.dp
+private fun showFailureAnimation() {
+ // TODO(b/282730134): implement.
+}
+
+private val entryShapeSize = 16.dp
+
+private val pinButtonSize = 84.dp
+
+// Pin button motion spec: http://shortn/_9TTIG6SoEa
+private val pinButtonPressedDuration = 100.milliseconds
+private val pinButtonPressedEasing = Easings.Linear
+private val pinButtonHoldTime = 33.milliseconds
+private val pinButtonReleasedDuration = 420.milliseconds
+private val pinButtonReleasedEasing = Easings.Standard
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/ConditionalModifiers.kt b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/ConditionalModifiers.kt
new file mode 100644
index 000000000000..83071d78c64d
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/compose/modifiers/ConditionalModifiers.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.compose.modifiers
+
+import androidx.compose.ui.Modifier
+
+/**
+ * Concatenates this modifier with another if `condition` is true.
+ *
+ * @param condition Whether or not to apply the modifiers.
+ * @param factory Creates the modifier to concatenate with the current one.
+ * @return a Modifier representing this modifier followed by other in sequence.
+ * @see Modifier.then
+ *
+ * This method allows inline conditional addition of modifiers to a modifier chain. Instead of
+ * writing
+ *
+ * ```
+ * val aModifier = Modifier.a()
+ * val bModifier = if(condition) aModifier.b() else aModifier
+ * Composable(modifier = bModifier)
+ * ```
+ *
+ * You can instead write
+ *
+ * ```
+ * Composable(modifier = Modifier.a().thenIf(condition){
+ * Modifier.b()
+ * }
+ * ```
+ *
+ * This makes the modifier chain easier to read.
+ *
+ * Note that unlike the non-factory version, the conditional modifier is recreated each time, and
+ * may never be created at all.
+ */
+inline fun Modifier.thenIf(condition: Boolean, crossinline factory: () -> Modifier): Modifier =
+ if (condition) this.then(factory()) else this
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 7c76281e4bdd..0e20444347fd 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
private val KEY_TIMESTAMP = "appliedTimestamp"
@@ -320,20 +321,20 @@ open class ClockRegistry(
}
}
- public fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
- scope.launch(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
+ public suspend fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
+ withContext(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
}
var currentClockId: ClockId
get() = settings?.clockId ?: fallbackClockId
set(value) {
- mutateSetting { it.copy(clockId = value) }
+ scope.launch(bgDispatcher) { mutateSetting { it.copy(clockId = value) } }
}
var seedColor: Int?
get() = settings?.seedColor
set(value) {
- mutateSetting { it.copy(seedColor = value) }
+ scope.launch(bgDispatcher) { mutateSetting { it.copy(seedColor = value) } }
}
init {
@@ -501,11 +502,25 @@ open class ClockRegistry(
fun createExampleClock(clockId: ClockId): ClockController? = createClock(clockId)
- fun registerClockChangeListener(listener: ClockChangeListener) =
+ /**
+ * Adds [listener] to receive future clock changes.
+ *
+ * Calling from main thread to make sure the access is thread safe.
+ */
+ fun registerClockChangeListener(listener: ClockChangeListener) {
+ assertMainThread()
clockChangeListeners.add(listener)
+ }
- fun unregisterClockChangeListener(listener: ClockChangeListener) =
+ /**
+ * Removes [listener] from future clock changes.
+ *
+ * Calling from main thread to make sure the access is thread safe.
+ */
+ fun unregisterClockChangeListener(listener: ClockChangeListener) {
+ assertMainThread()
clockChangeListeners.remove(listener)
+ }
fun createCurrentClock(): ClockController {
val clockId = currentClockId
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 252c8e343e0e..e557c8e5902a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -33,6 +33,7 @@ import com.android.systemui.plugins.ClockFaceConfig
import com.android.systemui.plugins.ClockFaceController
import com.android.systemui.plugins.ClockFaceEvents
import com.android.systemui.plugins.ClockSettings
+import com.android.systemui.plugins.WeatherData
import java.io.PrintWriter
import java.util.Locale
import java.util.TimeZone
@@ -50,6 +51,7 @@ class DefaultClockController(
private val layoutInflater: LayoutInflater,
private val resources: Resources,
private val settings: ClockSettings?,
+ private val hasStepClockAnimation: Boolean = false,
) : ClockController {
override val smallClock: DefaultClockFaceController
override val largeClock: LargeClockFaceController
@@ -170,7 +172,8 @@ class DefaultClockController(
view: AnimatableClockView,
seedColor: Int?,
) : DefaultClockFaceController(view, seedColor) {
- override val config = ClockFaceConfig(hasCustomPositionUpdatedAnimation = true)
+ override val config =
+ ClockFaceConfig(hasCustomPositionUpdatedAnimation = hasStepClockAnimation)
init {
animations = LargeClockAnimations(view, 0f, 0f)
@@ -225,6 +228,8 @@ class DefaultClockController(
clocks.forEach { it.refreshFormat() }
}
+
+ override fun onWeatherDataChanged(data: WeatherData) {}
}
open inner class DefaultClockAnimations(
@@ -271,6 +276,8 @@ class DefaultClockController(
// the top margin change in recomputePadding to make clock be centered
view.translationY = 0.5f * view.bottom * (1 - swipingFraction)
}
+
+ override fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float) {}
}
inner class LargeClockAnimations(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 0fd1b492c146..949641a7f75e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -29,10 +29,11 @@ const val DEFAULT_CLOCK_NAME = "Default Clock"
const val DEFAULT_CLOCK_ID = "DEFAULT"
/** Provides the default system clock */
-class DefaultClockProvider constructor(
+class DefaultClockProvider(
val ctx: Context,
val layoutInflater: LayoutInflater,
- val resources: Resources
+ val resources: Resources,
+ val hasStepClockAnimation: Boolean = false
) : ClockProvider {
override fun getClocks(): List<ClockMetadata> =
listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME))
@@ -42,7 +43,13 @@ class DefaultClockProvider constructor(
throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
}
- return DefaultClockController(ctx, layoutInflater, resources, settings)
+ return DefaultClockController(
+ ctx,
+ layoutInflater,
+ resources,
+ settings,
+ hasStepClockAnimation,
+ )
}
override fun getClockThumbnail(id: ClockId): Drawable? {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
index 6f363a4ffa26..08ee60204178 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
@@ -20,8 +20,6 @@ package com.android.systemui.shared.quickaffordance.shared.model
object KeyguardPreviewConstants {
const val MESSAGE_ID_HIDE_SMART_SPACE = 1111
const val KEY_HIDE_SMART_SPACE = "hide_smart_space"
- const val MESSAGE_ID_COLOR_OVERRIDE = 1234
- const val KEY_COLOR_OVERRIDE = "color_override" // ColorInt Encoded as string
const val MESSAGE_ID_SLOT_SELECTED = 1337
const val KEY_SLOT_ID = "slot_id"
const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
index 21218a2dc8e2..9f075e521126 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
@@ -16,13 +16,15 @@
package com.android.systemui.monet.dynamiccolor;
+import android.annotation.NonNull;
+
import com.android.systemui.monet.dislike.DislikeAnalyzer;
import com.android.systemui.monet.hct.Hct;
import com.android.systemui.monet.hct.ViewingConditions;
import com.android.systemui.monet.scheme.DynamicScheme;
import com.android.systemui.monet.scheme.Variant;
-/** Named colors, otherwise known as tokens, or roles, in the Material Design system.*/
+/** Named colors, otherwise known as tokens, or roles, in the Material Design system. */
// Prevent lint for Function.apply not being available on Android before API level 14 (4.0.1).
// "AndroidJdkLibsChecker" for Function, "NewApi" for Function.apply().
// A java_library Bazel rule with an Android constraint cannot skip these warnings without this
@@ -32,190 +34,148 @@ import com.android.systemui.monet.scheme.Variant;
public final class MaterialDynamicColors {
private static final double CONTAINER_ACCENT_TONE_DELTA = 15.0;
-
- public MaterialDynamicColors() {
- }
-
- /**
- * These colors were present in Android framework before Android U, and used by MDC controls.
- * They
- * should be avoided, if possible. It's unclear if they're used on multiple backgrounds, and if
- * they are, they can't be adjusted for contrast.* For now, they will be set with no background,
- * and those won't adjust for contrast, avoiding issues.
- *
- * <p>* For example, if the same color is on a white background _and_ black background,
- * there's no
- * way to increase contrast with either without losing contrast with the other.
- */
- // colorControlActivated documented as colorAccent in M3 & GM3.
- // colorAccent documented as colorSecondary in M3 and colorPrimary in GM3.
- // Android used Material's Container as Primary/Secondary/Tertiary at launch.
- // Therefore, this is a duplicated version of Primary Container.
- public static DynamicColor controlActivated() {
- return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
- }
+ public MaterialDynamicColors() {}
// Compatibility Keys Colors for Android
- public static DynamicColor primaryPaletteKeyColor() {
+ public DynamicColor primaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette, (s) -> s.primaryPalette.getKeyColor().getTone());
}
- public static DynamicColor secondaryPaletteKeyColor() {
+ public DynamicColor secondaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette, (s) -> s.secondaryPalette.getKeyColor().getTone());
}
- public static DynamicColor tertiaryPaletteKeyColor() {
+ public DynamicColor tertiaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette, (s) -> s.tertiaryPalette.getKeyColor().getTone());
}
- public static DynamicColor neutralPaletteKeyColor() {
+ public DynamicColor neutralPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.neutralPalette.getKeyColor().getTone());
}
- public static DynamicColor neutralVariantPaletteKeyColor() {
+ public DynamicColor neutralVariantPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.neutralVariantPalette,
(s) -> s.neutralVariantPalette.getKeyColor().getTone());
}
- private static ViewingConditions viewingConditionsForAlbers(DynamicScheme scheme) {
- return ViewingConditions.defaultWithBackgroundLstar(scheme.isDark ? 30.0 : 80.0);
- }
-
- private static boolean isFidelity(DynamicScheme scheme) {
- return scheme.variant == Variant.FIDELITY || scheme.variant == Variant.CONTENT;
- }
-
- private static boolean isMonochrome(DynamicScheme scheme) {
- return scheme.variant == Variant.MONOCHROME;
- }
-
- static double findDesiredChromaByTone(
- double hue, double chroma, double tone, boolean byDecreasingTone) {
- double answer = tone;
-
- Hct closestToChroma = Hct.from(hue, chroma, tone);
- if (closestToChroma.getChroma() < chroma) {
- double chromaPeak = closestToChroma.getChroma();
- while (closestToChroma.getChroma() < chroma) {
- answer += byDecreasingTone ? -1.0 : 1.0;
- Hct potentialSolution = Hct.from(hue, chroma, answer);
- if (chromaPeak > potentialSolution.getChroma()) {
- break;
- }
- if (Math.abs(potentialSolution.getChroma() - chroma) < 0.4) {
- break;
- }
-
- double potentialDelta = Math.abs(potentialSolution.getChroma() - chroma);
- double currentDelta = Math.abs(closestToChroma.getChroma() - chroma);
- if (potentialDelta < currentDelta) {
- closestToChroma = potentialSolution;
- }
- chromaPeak = Math.max(chromaPeak, potentialSolution.getChroma());
- }
- }
-
- return answer;
- }
-
- static double performAlbers(Hct prealbers, DynamicScheme scheme) {
- final Hct albersd = prealbers.inViewingConditions(viewingConditionsForAlbers(scheme));
- if (DynamicColor.tonePrefersLightForeground(prealbers.getTone())
- && !DynamicColor.toneAllowsLightForeground(albersd.getTone())) {
- return DynamicColor.enableLightForeground(prealbers.getTone());
- } else {
- return DynamicColor.enableLightForeground(albersd.getTone());
- }
- }
-
- public static DynamicColor highestSurface(DynamicScheme s) {
+ @NonNull
+ public DynamicColor highestSurface(@NonNull DynamicScheme s) {
return s.isDark ? surfaceBright() : surfaceDim();
}
- public static DynamicColor background() {
+ @NonNull
+ public DynamicColor background() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
}
- public static DynamicColor onBackground() {
+ @NonNull
+ public DynamicColor onBackground() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> background());
}
- public static DynamicColor surface() {
+ @NonNull
+ public DynamicColor surface() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
}
- public static DynamicColor inverseSurface() {
+ @NonNull
+ public DynamicColor inverseSurface() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 20.0);
}
- public static DynamicColor surfaceBright() {
+ @NonNull
+ public DynamicColor surfaceBright() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 24.0 : 98.0);
}
- public static DynamicColor surfaceDim() {
+ @NonNull
+ public DynamicColor surfaceDim() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 87.0);
}
- public static DynamicColor surfaceContainerLowest() {
+ @NonNull
+ public DynamicColor surfaceContainerLowest() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 4.0 : 100.0);
}
- public static DynamicColor surfaceContainerLow() {
+ @NonNull
+ public DynamicColor surfaceContainerLow() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 96.0);
}
- public static DynamicColor surfaceContainer() {
+ @NonNull
+ public DynamicColor surfaceContainer() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 12.0 : 94.0);
}
- public static DynamicColor surfaceContainerHigh() {
+ @NonNull
+ public DynamicColor surfaceContainerHigh() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 17.0 : 92.0);
}
- public static DynamicColor surfaceContainerHighest() {
+ @NonNull
+ public DynamicColor surfaceContainerHighest() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 22.0 : 90.0);
}
- public static DynamicColor onSurface() {
+ @NonNull
+ public DynamicColor onSurface() {
return DynamicColor.fromPalette(
- (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, this::highestSurface);
}
- public static DynamicColor inverseOnSurface() {
+ @NonNull
+ public DynamicColor inverseOnSurface() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.isDark ? 20.0 : 95.0, (s) -> inverseSurface());
}
- public static DynamicColor surfaceVariant() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 30.0 : 90.0);
+ @NonNull
+ public DynamicColor surfaceVariant() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 90.0);
}
- public static DynamicColor onSurfaceVariant() {
+ @NonNull
+ public DynamicColor onSurfaceVariant() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0,
- (s) -> surfaceVariant());
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0, (s) -> surfaceVariant());
}
- public static DynamicColor outline() {
+ @NonNull
+ public DynamicColor outline() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> 50.0, MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 60.0 : 50.0, this::highestSurface);
}
- public static DynamicColor outlineVariant() {
+ @NonNull
+ public DynamicColor outlineVariant() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0, this::highestSurface);
+ }
+
+ @NonNull
+ public DynamicColor shadow() {
+ return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> 0.0);
}
- public static DynamicColor primaryContainer() {
+ @NonNull
+ public DynamicColor scrim() {
+ return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> 0.0);
+ }
+
+ @NonNull
+ public DynamicColor surfaceTint() {
+ return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 80.0 : 40.0);
+ }
+
+ @NonNull
+ public DynamicColor primaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -227,10 +187,11 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 30.0 : 90.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onPrimaryContainer() {
+ @NonNull
+ public DynamicColor onPrimaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -246,7 +207,8 @@ public final class MaterialDynamicColors {
null);
}
- public static DynamicColor primary() {
+ @NonNull
+ public DynamicColor primary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -255,7 +217,7 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 80.0 : 40.0;
},
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -263,12 +225,14 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor inversePrimary() {
+ @NonNull
+ public DynamicColor inversePrimary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette, (s) -> s.isDark ? 40.0 : 80.0, (s) -> inverseSurface());
}
- public static DynamicColor onPrimary() {
+ @NonNull
+ public DynamicColor onPrimary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -280,7 +244,8 @@ public final class MaterialDynamicColors {
(s) -> primary());
}
- public static DynamicColor secondaryContainer() {
+ @NonNull
+ public DynamicColor secondaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -300,10 +265,11 @@ public final class MaterialDynamicColors {
answer = performAlbers(s.secondaryPalette.getHct(answer), s);
return answer;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onSecondaryContainer() {
+ @NonNull
+ public DynamicColor onSecondaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -315,11 +281,12 @@ public final class MaterialDynamicColors {
(s) -> secondaryContainer());
}
- public static DynamicColor secondary() {
+ @NonNull
+ public DynamicColor secondary() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> s.isDark ? 80.0 : 40.0,
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -327,7 +294,8 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onSecondary() {
+ @NonNull
+ public DynamicColor onSecondary() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -339,7 +307,8 @@ public final class MaterialDynamicColors {
(s) -> secondary());
}
- public static DynamicColor tertiaryContainer() {
+ @NonNull
+ public DynamicColor tertiaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -354,10 +323,11 @@ public final class MaterialDynamicColors {
final Hct proposedHct = s.tertiaryPalette.getHct(albersTone);
return DislikeAnalyzer.fixIfDisliked(proposedHct).getTone();
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onTertiaryContainer() {
+ @NonNull
+ public DynamicColor onTertiaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -372,7 +342,8 @@ public final class MaterialDynamicColors {
(s) -> tertiaryContainer());
}
- public static DynamicColor tertiary() {
+ @NonNull
+ public DynamicColor tertiary() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -381,7 +352,7 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 80.0 : 40.0;
},
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -389,7 +360,8 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onTertiary() {
+ @NonNull
+ public DynamicColor onTertiary() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -401,22 +373,24 @@ public final class MaterialDynamicColors {
(s) -> tertiary());
}
- public static DynamicColor errorContainer() {
+ @NonNull
+ public DynamicColor errorContainer() {
return DynamicColor.fromPalette(
- (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0, this::highestSurface);
}
- public static DynamicColor onErrorContainer() {
+ @NonNull
+ public DynamicColor onErrorContainer() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> errorContainer());
}
- public static DynamicColor error() {
+ @NonNull
+ public DynamicColor error() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette,
(s) -> s.isDark ? 80.0 : 40.0,
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -424,113 +398,138 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onError() {
+ @NonNull
+ public DynamicColor onError() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> error());
}
- public static DynamicColor primaryFixed() {
+ @NonNull
+ public DynamicColor primaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 100.0 : 10.0;
+ return 40.0;
}
return 90.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor primaryFixedDim() {
+ @NonNull
+ public DynamicColor primaryFixedDim() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 90.0 : 20.0;
+ return 30.0;
}
return 80.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onPrimaryFixed() {
+ @NonNull
+ public DynamicColor onPrimaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 10.0 : 90.0;
+ return 100.0;
}
return 10.0;
},
(s) -> primaryFixedDim());
}
- public static DynamicColor onPrimaryFixedVariant() {
+ @NonNull
+ public DynamicColor onPrimaryFixedVariant() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 30.0 : 70.0;
+ return 90.0;
}
return 30.0;
},
(s) -> primaryFixedDim());
}
- public static DynamicColor secondaryFixed() {
+ @NonNull
+ public DynamicColor secondaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 80.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 80.0 : 90.0, this::highestSurface);
}
- public static DynamicColor secondaryFixedDim() {
+ @NonNull
+ public DynamicColor secondaryFixedDim() {
return DynamicColor.fromPalette(
- (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 70.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 70.0 : 80.0, this::highestSurface);
}
- public static DynamicColor onSecondaryFixed() {
+ @NonNull
+ public DynamicColor onSecondaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette, (s) -> 10.0, (s) -> secondaryFixedDim());
}
- public static DynamicColor onSecondaryFixedVariant() {
+ @NonNull
+ public DynamicColor onSecondaryFixedVariant() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> isMonochrome(s) ? 25.0 : 30.0,
(s) -> secondaryFixedDim());
}
- public static DynamicColor tertiaryFixed() {
+ @NonNull
+ public DynamicColor tertiaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 40.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 40.0 : 90.0, this::highestSurface);
}
- public static DynamicColor tertiaryFixedDim() {
+ @NonNull
+ public DynamicColor tertiaryFixedDim() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 30.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 30.0 : 80.0, this::highestSurface);
}
- public static DynamicColor onTertiaryFixed() {
+ @NonNull
+ public DynamicColor onTertiaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 90.0 : 10.0,
- (s) -> tertiaryFixedDim());
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 100.0 : 10.0, (s) -> tertiaryFixedDim());
}
- public static DynamicColor onTertiaryFixedVariant() {
+ @NonNull
+ public DynamicColor onTertiaryFixedVariant() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 70.0 : 30.0,
- (s) -> tertiaryFixedDim());
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 90.0 : 30.0, (s) -> tertiaryFixedDim());
+ }
+
+ /**
+ * These colors were present in Android framework before Android U, and used by MDC controls. They
+ * should be avoided, if possible. It's unclear if they're used on multiple backgrounds, and if
+ * they are, they can't be adjusted for contrast.* For now, they will be set with no background,
+ * and those won't adjust for contrast, avoiding issues.
+ *
+ * <p>* For example, if the same color is on a white background _and_ black background, there's no
+ * way to increase contrast with either without losing contrast with the other.
+ */
+ // colorControlActivated documented as colorAccent in M3 & GM3.
+ // colorAccent documented as colorSecondary in M3 and colorPrimary in GM3.
+ // Android used Material's Container as Primary/Secondary/Tertiary at launch.
+ // Therefore, this is a duplicated version of Primary Container.
+ @NonNull
+ public DynamicColor controlActivated() {
+ return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
}
// colorControlNormal documented as textColorSecondary in M3 & GM3.
// In Material, textColorSecondary points to onSurfaceVariant in the non-disabled state,
// which is Neutral Variant T30/80 in light/dark.
- public static DynamicColor controlNormal() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 80.0 : 30.0);
+ @NonNull
+ public DynamicColor controlNormal() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0);
}
// colorControlHighlight documented, in both M3 & GM3:
@@ -541,7 +540,8 @@ public final class MaterialDynamicColors {
// DynamicColors do not support alpha currently, and _may_ not need it for this use case,
// depending on how MDC resolved alpha for the other cases.
// Returning black in dark mode, white in light mode.
- public static DynamicColor controlHighlight() {
+ @NonNull
+ public DynamicColor controlHighlight() {
return new DynamicColor(
s -> 0.0,
s -> 0.0,
@@ -549,40 +549,92 @@ public final class MaterialDynamicColors {
s -> s.isDark ? 0.20 : 0.12,
null,
scheme ->
-
- DynamicColor.toneMinContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
- scheme, null),
+ DynamicColor.toneMinContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
scheme ->
- DynamicColor.toneMaxContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
- scheme, null),
+ DynamicColor.toneMaxContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
null);
}
// textColorPrimaryInverse documented, in both M3 & GM3, documented as N10/N90.
- public static DynamicColor textPrimaryInverse() {
+ @NonNull
+ public DynamicColor textPrimaryInverse() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorSecondaryInverse and textColorTertiaryInverse both documented, in both M3 & GM3, as
// NV30/NV80
- public static DynamicColor textSecondaryAndTertiaryInverse() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 30.0 : 80.0);
+ @NonNull
+ public DynamicColor textSecondaryAndTertiaryInverse() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0);
}
// textColorPrimaryInverseDisableOnly documented, in both M3 & GM3, as N10/N90
- public static DynamicColor textPrimaryInverseDisableOnly() {
+ @NonNull
+ public DynamicColor textPrimaryInverseDisableOnly() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorSecondaryInverse and textColorTertiaryInverse in disabled state both documented,
// in both M3 & GM3, as N10/N90
- public static DynamicColor textSecondaryAndTertiaryInverseDisabled() {
+ @NonNull
+ public DynamicColor textSecondaryAndTertiaryInverseDisabled() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorHintInverse documented, in both M3 & GM3, as N10/N90
- public static DynamicColor textHintInverse() {
+ @NonNull
+ public DynamicColor textHintInverse() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
-}
+
+ private static ViewingConditions viewingConditionsForAlbers(DynamicScheme scheme) {
+ return ViewingConditions.defaultWithBackgroundLstar(scheme.isDark ? 30.0 : 80.0);
+ }
+
+ private static boolean isFidelity(DynamicScheme scheme) {
+ return scheme.variant == Variant.FIDELITY || scheme.variant == Variant.CONTENT;
+ }
+
+ private static boolean isMonochrome(DynamicScheme scheme) {
+ return scheme.variant == Variant.MONOCHROME;
+ }
+
+ static double findDesiredChromaByTone(
+ double hue, double chroma, double tone, boolean byDecreasingTone) {
+ double answer = tone;
+
+ Hct closestToChroma = Hct.from(hue, chroma, tone);
+ if (closestToChroma.getChroma() < chroma) {
+ double chromaPeak = closestToChroma.getChroma();
+ while (closestToChroma.getChroma() < chroma) {
+ answer += byDecreasingTone ? -1.0 : 1.0;
+ Hct potentialSolution = Hct.from(hue, chroma, answer);
+ if (chromaPeak > potentialSolution.getChroma()) {
+ break;
+ }
+ if (Math.abs(potentialSolution.getChroma() - chroma) < 0.4) {
+ break;
+ }
+
+ double potentialDelta = Math.abs(potentialSolution.getChroma() - chroma);
+ double currentDelta = Math.abs(closestToChroma.getChroma() - chroma);
+ if (potentialDelta < currentDelta) {
+ closestToChroma = potentialSolution;
+ }
+ chromaPeak = Math.max(chromaPeak, potentialSolution.getChroma());
+ }
+ }
+
+ return answer;
+ }
+
+ static double performAlbers(Hct prealbers, DynamicScheme scheme) {
+ final Hct albersd = prealbers.inViewingConditions(viewingConditionsForAlbers(scheme));
+ if (DynamicColor.tonePrefersLightForeground(prealbers.getTone())
+ && !DynamicColor.toneAllowsLightForeground(albersd.getTone())) {
+ return DynamicColor.enableLightForeground(prealbers.getTone());
+ } else {
+ return DynamicColor.enableLightForeground(albersd.getTone());
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 5d0a3af74e5d..3ae328e67e3d 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -74,18 +74,10 @@ interface ClockController {
resources: Resources,
dozeFraction: Float,
foldFraction: Float,
- ) {
- events.onColorPaletteChanged(resources)
- smallClock.animations.doze(dozeFraction)
- largeClock.animations.doze(dozeFraction)
- smallClock.animations.fold(foldFraction)
- largeClock.animations.fold(foldFraction)
- smallClock.events.onTimeTick()
- largeClock.events.onTimeTick()
- }
+ )
/** Optional method for dumping debug information */
- fun dump(pw: PrintWriter) {}
+ fun dump(pw: PrintWriter)
}
/** Interface for a specific clock face version rendered by the clock */
@@ -109,37 +101,37 @@ interface ClockFaceController {
/** Events that should call when various rendering parameters change */
interface ClockEvents {
/** Call whenever timezone changes */
- fun onTimeZoneChanged(timeZone: TimeZone) {}
+ fun onTimeZoneChanged(timeZone: TimeZone)
/** Call whenever the text time format changes (12hr vs 24hr) */
- fun onTimeFormatChanged(is24Hr: Boolean) {}
+ fun onTimeFormatChanged(is24Hr: Boolean)
/** Call whenever the locale changes */
- fun onLocaleChanged(locale: Locale) {}
+ fun onLocaleChanged(locale: Locale)
/** Call whenever the color palette should update */
- fun onColorPaletteChanged(resources: Resources) {}
+ fun onColorPaletteChanged(resources: Resources)
/** Call if the seed color has changed and should be updated */
- fun onSeedColorChanged(seedColor: Int?) {}
+ fun onSeedColorChanged(seedColor: Int?)
/** Call whenever the weather data should update */
- fun onWeatherDataChanged(data: WeatherData) {}
+ fun onWeatherDataChanged(data: WeatherData)
}
/** Methods which trigger various clock animations */
interface ClockAnimations {
/** Runs an enter animation (if any) */
- fun enter() {}
+ fun enter()
/** Sets how far into AOD the device currently is. */
- fun doze(fraction: Float) {}
+ fun doze(fraction: Float)
/** Sets how far into the folding animation the device is. */
- fun fold(fraction: Float) {}
+ fun fold(fraction: Float)
/** Runs the battery animation (if any). */
- fun charge() {}
+ fun charge()
/**
* Runs when the clock's position changed during the move animation.
@@ -150,32 +142,32 @@ interface ClockAnimations {
* @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
* it finished moving.
*/
- fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float) {}
+ fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
/**
* Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
* 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
*/
- fun onPickerCarouselSwiping(swipingFraction: Float) {}
+ fun onPickerCarouselSwiping(swipingFraction: Float)
}
/** Events that have specific data about the related face */
interface ClockFaceEvents {
/** Call every time tick */
- fun onTimeTick() {}
+ fun onTimeTick()
/**
* Region Darkness specific to the clock face.
* - isRegionDark = dark theme -> clock should be light
* - !isRegionDark = light theme -> clock should be dark
*/
- fun onRegionDarknessChanged(isRegionDark: Boolean) {}
+ fun onRegionDarknessChanged(isRegionDark: Boolean)
/**
* Call whenever font settings change. Pass in a target font size in pixels. The specific clock
* design is allowed to ignore this target size on a case-by-case basis.
*/
- fun onFontSettingChanged(fontSizePx: Float) {}
+ fun onFontSettingChanged(fontSizePx: Float)
/**
* Target region information for the clock face. For small clock, this will match the bounds of
@@ -184,7 +176,7 @@ interface ClockFaceEvents {
* render within the centered targetRect to avoid obstructing other elements. The specified
* targetRegion is relative to the parent view.
*/
- fun onTargetRegionChanged(targetRegion: Rect?) {}
+ fun onTargetRegionChanged(targetRegion: Rect?)
}
/** Tick rates for clocks */
diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags
index 02d55104c288..1f47e724e48c 100644
--- a/packages/SystemUI/proguard_common.flags
+++ b/packages/SystemUI/proguard_common.flags
@@ -64,15 +64,16 @@
# The plugins, log & common subpackages act as shared libraries that might be referenced in
# dynamically-loaded plugin APKs.
--keep class com.android.systemui.plugins.** {
- *;
-}
--keep class com.android.systemui.log.** {
- *;
-}
--keep class com.android.systemui.common.** {
- *;
-}
+-keep class com.android.systemui.plugins.** { *; }
+-keep class com.android.systemui.log.ConstantStringsLoggerImpl { *; }
+-keep class com.android.systemui.log.ConstantStringsLogger { *; }
+-keep class com.android.systemui.log.LogBuffer { *; }
+-keep class com.android.systemui.log.LogcatEchoTrackerDebug { *; }
+-keep class com.android.systemui.log.LogcatEchoTracker { *; }
+-keep class com.android.systemui.log.LogcatEchoTrackerProd { *; }
+-keep class com.android.systemui.log.LogLevel { *; }
+-keep class com.android.systemui.log.LogMessageImpl { *; }
+-keep class com.android.systemui.log.LogMessage { *; }
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
*;
}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 330676b3dd5f..01c5443e9355 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -82,7 +82,7 @@
androidprv:layout_constraintGuide_percent="0"
android:orientation="horizontal" />
- <androidx.constraintlayout.helper.widget.Flow
+ <com.android.keyguard.KeyguardPinFlowView
android:id="@+id/flow1"
android:layout_width="0dp"
android:layout_height="0dp"
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 3770c7d5fb27..5d8c508d20c1 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Unesite svoj PIN"</string>
+ <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Unesite PIN"</string>
<string name="keyguard_enter_pin" msgid="8114529922480276834">"Unesite PIN"</string>
<string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Unesite uzorak"</string>
<string name="keyguard_enter_pattern" msgid="7616595160901084119">"Unesite uzorak"</string>
@@ -98,8 +98,8 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Otključavanje SIM-a…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji sadrži 4 do 8 brojeva."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba sadržavati najmanje 8 brojeva."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Pogrešno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Pogrešno ste napisali lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"PIN za SIM karticu je netačan. Za otključavanje uređaja sada se morate obratiti svom operateru."</string>
<string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{PIN kôd za SIM je netačan. Imate još # pokušaj prije nego što budete morali kontaktirati mobilnog operatera da vam otključa uređaj.}one{PIN kôd za SIM je netačan. Imate još # pokušaj. }few{PIN kôd za SIM je netačan. Imate još # pokušaja. }other{PIN kôd za SIM je netačan. Imate još # pokušaja. }}"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 8b31fe05e5d6..04b6a3d7bfd8 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -98,8 +98,8 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"S\'està desbloquejant la targeta SIM…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Escriu un PIN que tingui entre 4 i 8 números."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"El codi PUK ha de tenir 8 números o més."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Has escrit el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has escrit la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El codi PIN de la SIM no és correcte. Contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</string>
<string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{El codi PIN de la SIM no és correcte. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}many{El codi PIN de la SIM no és correcte. Et queden # intents. }other{El codi PIN de la SIM no és correcte. Et queden # intents. }}"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 23e566816a41..d042b78060ea 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Ξεκλείδωμα SIM…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Ο κωδικός PUK θα πρέπει να περιέχει τουλάχιστον 8 αριθμούς."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Έχετε πληκτρολογήσει τον αριθμό PIN εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Έχετε πληκτρολογήσει το PIN σας εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος<xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Λανθασμένος κωδικός PIN κάρτας SIM. Θα πρέπει να επικοινωνήσετε με την εταιρεία κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας."</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index be03ec47859a..4d4c3f9d826e 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -41,7 +41,7 @@
<string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Gehitu SIM bat."</string>
<string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIMa falta da, edo ezin da irakurri. Gehitu SIM bat."</string>
<string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ezin da erabili SIMa."</string>
- <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Betiko desaktibatu da SIMa.\n Jarri harremanetan operadorearekin beste SIM bat eskuratzeko."</string>
+ <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Betiko desaktibatu da SIMa.\n Jarri operadorearekin harremanetan beste SIM bat eskuratzeko."</string>
<string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIMa blokeatuta dago."</string>
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMa PUKaren bidez desblokeatu behar da."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMa desblokeatzen…"</string>
@@ -92,7 +92,7 @@
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Idatzi \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartelaren PINa."</string>
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Desgaitu eSIM txartela gailua zerbitzu mugikorrik gabe erabiltzeko."</string>
<string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. Xehetasunak lortzeko, jarri operadorearekin harremanetan."</string>
- <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Desgaitu egin da \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIM txartela. Aurrera egiteko, idatzi PUK kodea. Xehetasunak jakiteko, jarri operadorearekin harremanetan."</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Desgaitu egin da \"<xliff:g id="CARRIER">%1$s</xliff:g>\" operadorearen SIMa. Aurrera egiteko, idatzi PUK kodea. Xehetasunak jakiteko, jarri operadorearekin harremanetan."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Idatzi erabili nahi duzun PIN kodea"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Berretsi erabili nahi duzun PIN kodea"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIMa desblokeatzen…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 52b204f54e63..10c7aafd9ab2 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"सिम अनलॉक हो रहा है…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"कोई ऐसा पिन लिखें, जिसमें 4 से 8 अंक हों."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड 8 या ज़्यादा संख्या वाला होना चाहिए."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"आप अपना पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"<xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत पिन डाला जा चुका है. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"गलत SIM पिन कोड, अपने डिवाइस को अनलॉक करने के लिए अब आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index b5034d8cb64c..045c9045563d 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Otključavanje SIM-a…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kôd treba imati 8 brojeva ili više."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Netočno ste unijeli zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netočan PIN kôd SIM kartice; sada morate kontaktirati svog mobilnog operatera da bi otključao vaš uređaj."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 28d19106faaf..666f9b147f27 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -112,9 +112,9 @@
<string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"デバイスの再起動後はパターンの入力が必要になります"</string>
<string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"デバイスの再起動後は PIN の入力が必要になります"</string>
<string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"デバイスの再起動後はパスワードの入力が必要になります"</string>
- <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"セキュリティを強化するには代わりにパターンを使用してください"</string>
- <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"セキュリティを強化するには代わりに PIN を使用してください"</string>
- <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"セキュリティを強化するには代わりにパスワードを使用してください"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"画面ロックを解除するにはパターンを入力してください"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"画面ロックを解除するには PIN を入力してください"</string>
+ <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"画面ロックを解除するにはパスワードを入力してください"</string>
<string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"デバイスは管理者によりロックされています"</string>
<string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"デバイスは手動でロックされました"</string>
<string name="kg_face_not_recognized" msgid="7903950626744419160">"認識されませんでした"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index bc8fd4064c85..8b0d60ce2555 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -87,7 +87,7 @@
<string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"ತಪ್ಪಾದ ಪಿನ್‌ನೊಂದಿಗೆ ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ"</string>
<string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"ತಪ್ಪಾದ ಪ್ಯಾಟರ್ನ್‌ನೊಂದಿಗೆ ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ"</string>
<string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ನೊಂದಿಗೆ ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ"</string>
- <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{# ಸೆಕೆಂಡಿನಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}one{# ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}other{# ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}}"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{# ಸೆಕೆಂಡಿನ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}one{# ಸೆಕೆಂಡುಗಳ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}other{# ಸೆಕೆಂಡುಗಳ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.}}"</string>
<string name="kg_sim_pin_instructions" msgid="1942424305184242951">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ."</string>
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗಾಗಿ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ."</string>
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ಮೊಬೈಲ್ ಸೇವೆ ಇಲ್ಲದೆ ಸಾಧನವನ್ನು ಬಳಸಲು eSIM ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ."</string>
@@ -98,9 +98,9 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIM ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ ಪಿನ್‌ ಟೈಪ್ ಮಾಡಿ."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK ಕೋಡ್ 8 ಅಥವಾ ಹೆಚ್ಚು ಸಂಖ್ಯೆಗಳನ್ನು ಹೊಂದಿರಬೇಕು."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ದೀರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್‌ ಅನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ್ದೀರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್‌ ಅನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ಸಿಮ್‌ ಪಿನ್‌ ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನೀವು ಈ ಕೂಡಲೇ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು."</string>
<string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡುವುದಕ್ಕಾಗಿ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ.}one{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. }other{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. }}"</string>
<string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ಸಿಮ್‌ ನಿಷ್ಪ್ರಯೋಜಕವಾಗಿದೆ. ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 5fadaabc5e3d..cfd053c12d44 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -58,7 +58,7 @@
<string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"잘못된 패턴입니다. 다시 시도해 주세요."</string>
<string name="kg_wrong_password" msgid="4143127991071670512">"잘못된 비밀번호"</string>
<string name="kg_wrong_password_try_again" msgid="6602878676125765920">"잘못된 비밀번호입니다. 다시 시도해 주세요."</string>
- <string name="kg_wrong_pin" msgid="4160978845968732624">"PIN 오류"</string>
+ <string name="kg_wrong_pin" msgid="4160978845968732624">"잘못된 PIN"</string>
<string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"잘못된 PIN입니다. 다시 시도해 주세요."</string>
<string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"또는 지문으로 잠금 해제하세요."</string>
<string name="kg_fp_not_recognized" msgid="5183108260932029241">"지문이 인식되지 않았습니다."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 6fab1908fb2f..f32d27ff52f2 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -45,9 +45,9 @@
<string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIM карта кулпуланган."</string>
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIM карта PUK менен кулпуланган."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIM картанын кулпусу ачылууда…"</string>
- <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN-коддун аймагы"</string>
+ <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN коддун аймагы"</string>
<string name="keyguard_accessibility_password" msgid="3524161948484801450">"Түзмөктүн сырсөзү"</string>
- <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM-картанын PIN-кодунун аймагы"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM-картанын PIN кодунун аймагы"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM-картанын PUK-кодунун аймагы"</string>
<string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Өчүрүү"</string>
<string name="disable_carrier_button_text" msgid="7153361131709275746">"eSIM-картаны өчүрүү"</string>
@@ -58,7 +58,7 @@
<string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"Графклк ачкч тура эмс. Кайтлап крүңз."</string>
<string name="kg_wrong_password" msgid="4143127991071670512">"Сырсөз туура эмес"</string>
<string name="kg_wrong_password_try_again" msgid="6602878676125765920">"Сырсөз туура эмес. Кайтлап крүңз."</string>
- <string name="kg_wrong_pin" msgid="4160978845968732624">"PIN-код туура эмес"</string>
+ <string name="kg_wrong_pin" msgid="4160978845968732624">"PIN код туура эмес"</string>
<string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"PIN кд тура эмс. Кайтлап крүңз."</string>
<string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"Болбосо манжа изи менен кулпусун ачыңыз"</string>
<string name="kg_fp_not_recognized" msgid="5183108260932029241">"Манжа изи таанылган жок"</string>
@@ -88,20 +88,20 @@
<string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Туура эмес графикалык ачкыч менен өтө көп аракет"</string>
<string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Туура эмес сырсөз менен өтө көп аракет"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{# секунддан кийин кайталаңыз.}other{# секунддан кийин кайталаңыз.}}"</string>
- <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"SIM-картанын PIN-кодун киргизиңиз."</string>
- <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" SIM-картасынын PIN-кодун киргизиңиз."</string>
+ <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"SIM-картанын PIN кодун киргизиңиз."</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" SIM-картасынын PIN кодун киргизиңиз."</string>
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Түзмөктү мобилдик кызматсыз колдонуу үчүн eSIM-картаны өчүрүңүз."</string>
<string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. Анын чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"Эми SIM-картанын \"<xliff:g id="CARRIER">%1$s</xliff:g>\" байланыш оператору өчүрүлдү. Улантуу үчүн PUK-кодду киргизиңиз. Анын чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз."</string>
- <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Сиз каалаган PIN-кодду териңиз"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Сиз каалаган PIN-кодду ырастаңыз"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Сиз каалаган PIN кодду териңиз"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Сиз каалаган PIN кодду ырастаңыз"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIM картанын кулпусу ачылууда…"</string>
- <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4–8 сандан турган PIN-кодду териңиз."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4–8 сандан турган PIN кодду териңиз."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-код 8 же андан көп сандан турушу керек."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Түзмөктү ачуучу графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
- <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-картанын PIN-коду туура эмес. Эми түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуңузга кайрылышыңыз керек."</string>
+ <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-картанын PIN коду туура эмес. Эми түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуңузга кайрылышыңыз керек."</string>
<string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM-картанын PIN коду туура эмес киргизилди. # аракет калды. Болбосо, түзмөктү бөгөттөн чыгаруу үчүн операторуңузга кайрылышыңыз керек болот.}other{SIM-картанын PIN коду туура эмес киргизилди. # аракет калды. }}"</string>
<string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-карта жараксыз. Байланыш операторуңузга кайрылыңыз."</string>
<string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM-картанын PUK коду туура эмес киргизилди. SIM-картанын биротоло жарактан чыгаарына # аракет калды.}other{SIM-картанын PUK коду туура эмес киргизилди. SIM-картанын биротоло жарактан чыгаарына # аракет калды.}}"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 99e35f9936b5..e39cc9547eb9 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Се отклучува SIM-картичката…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Внесете PIN што содржи 4 - 8 броеви."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-кодот треба да содржи 8 или повеќе броеви."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Погрешно сте го напишале вашиот PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Внесовте погрешен PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно по <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Погрешно сте ја напишале вашата лозинка <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Погрешно сте ја нацртале вашата шема за отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Погрешен PIN-код за SIM, сега мора да контактирате со вашиот оператор за да го отклучите уредот."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index eefc4919420e..54def0c95583 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIM-н түгжээг тайлж байна…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4-8 тооноос бүтэх ПИН-г оруулна уу."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Та ПИН кодоо <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Та нууц үгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-н ПИН кодыг буруу оруулсан тул та төхөөрөмжийнхөө түгжээг тайлахын тулд оператор компанитайгаа холбогдоно уу."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 82245319ffc5..206bdf2b36b8 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"सिम अनलॉक करत आहे…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ते 8 अंकांचा पिन टाईप करा."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड 8 अंकी किंवा त्यापेक्षा अधिकचा असावा."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तुम्ही तुमचा PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तुम्ही तुमचा पिन <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तुम्ही तुमचा पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"सिम पिन कोड चुकीचा आहे तुम्ही आता तुमचे डिव्हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधावा."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index d7cd73022a7e..40f16871c56f 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIM कार्ड अनलक गरिँदै छ…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"४ देखि ८ वटा नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK कोड ८ वा सो भन्दा बढी नम्बरको हुनु पर्छ।"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो PIN प्रविष्ट गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत PIN टाइप गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो गलत पासवर्ड प्रविष्ट गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो अनलक प्याटर्न कोर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM को PIN कोड गलत छ। तपाईंले अब आफ्नो यन्त्र खोल्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नै पर्ने हुन्छ।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index 97609678b3b7..bcf59847afa5 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -49,7 +49,7 @@
<string name="keyguard_accessibility_password" msgid="3524161948484801450">"ଡିଭାଇସ୍ ପାସ୍‍ୱର୍ଡ"</string>
<string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM PIN ଅଞ୍ଚଳ"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM PUK ଅଞ୍ଚଳ"</string>
- <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="disable_carrier_button_text" msgid="7153361131709275746">"eSIM ଅକ୍ଷମ କରନ୍ତୁ"</string>
<string name="error_disable_esim_title" msgid="3802652622784813119">"eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="error_disable_esim_msg" msgid="2441188596467999327">"ଗୋଟିଏ ତ୍ରୁଟି କାରଣରୁ eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ।"</string>
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIMକୁ ଅନଲକ କରାଯାଉଛି…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ରୁ 8 ନମ୍ବର ବିଶିଷ୍ଟ ଏକ PIN ଟାଇପ୍ କରନ୍ତୁ।"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK କୋଡ୍‍‍ରେ 8ଟି କିମ୍ବା ଅଧିକ ନମ୍ବର ରହିଥାଏ।"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ଆପଣଙ୍କ PIN ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଟାଇପ୍‍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଆପଣଙ୍କ PIN ଟାଇପ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ଆପଣଙ୍କ ପାସ୍‌ୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ଆପଣଙ୍କ ଲକ୍‍ ଖୋଲିବା ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ଭୁଲ SIM PIN କୋଡ, ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ କରିବା ପାଇଁ ଏବେ ହିଁ ନିଜ କ୍ଯାରିଅରଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 3be5b7ff984b..868bf2210d5e 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -98,8 +98,8 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Odblokowuję kartę SIM…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Wpisz kod PIN o długości od 4 do 8 cyfr."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Kod PUK musi mieć co najmniej 8 cyfr."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowy kod PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> został wpisany nieprawidłowy kod PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nieprawidłowy kod PIN karty SIM. Musisz teraz skontaktować się z operatorem, by odblokował Twoje urządzenie."</string>
<string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próbę, zanim trzeba będzie skontaktować się z operatorem, aby odblokował Twoje urządzenie.}few{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próby. }many{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # prób. }other{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próby. }}"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 8ae6018a6221..e1a0c43202c4 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Introduza o PIN."</string>
+ <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Introduza o PIN"</string>
<string name="keyguard_enter_pin" msgid="8114529922480276834">"Introduza o PIN"</string>
<string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Introduza o padrão"</string>
<string name="keyguard_enter_pattern" msgid="7616595160901084119">"Desenhe o padrão"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml
new file mode 100644
index 000000000000..2a8092010a37
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<resources>
+ <!-- Invisibility to use for the date & weather view when it is disabled by a clock -->
+ <integer name="keyguard_date_weather_view_invisibility">8</integer>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 439c836cd53d..f8bf307800cc 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"మీ PINను ఎంటర్ చేయండి"</string>
<string name="keyguard_enter_pin" msgid="8114529922480276834">"PINను ఎంటర్ చేయండి"</string>
<string name="keyguard_enter_your_pattern" msgid="351503370332324745">"మీ ఆకృతిని ఎంటర్ చేయండి"</string>
<string name="keyguard_enter_pattern" msgid="7616595160901084119">"ఆకృతిని గీయండి"</string>
@@ -58,7 +58,7 @@
<string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"ఆకృతి తప్పు. మళ్లీ గీయండి."</string>
<string name="kg_wrong_password" msgid="4143127991071670512">"పాస్‌వర్డ్ తప్పు"</string>
<string name="kg_wrong_password_try_again" msgid="6602878676125765920">"పాస్‌వర్డ్ తప్పు. రీట్రై."</string>
- <string name="kg_wrong_pin" msgid="4160978845968732624">"పిన్ తప్పు"</string>
+ <string name="kg_wrong_pin" msgid="4160978845968732624">"PIN తప్పు"</string>
<string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"PIN తప్పు. రీట్రై చేయండి."</string>
<string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"లేదా వేలిముద్రతో అన్‌లాక్ చేయండి"</string>
<string name="kg_fp_not_recognized" msgid="5183108260932029241">"వేలిముద్ర గుర్తించబడలేదు"</string>
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIMను అన్‌లాక్ చేస్తోంది…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 నుండి 8 సంఖ్యలు ఉండే పిన్‌ను టైప్ చేయండి."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK కోడ్ అనేది 8 లేదా అంతకంటే ఎక్కువ సంఖ్యలు ఉండాలి."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"మీరు మీ పిన్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ట్రై చేయండి."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"మీ PINను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్ల తర్వాత మళ్లీ ట్రై చేయండి."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ట్రై చేయండి."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ట్రై చేయండి."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM పిన్ కోడ్ తప్పు, ఇప్పుడు మీ డివైజ్‌ను అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ను సంప్రదించాలి."</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 4d9102c0fefd..70328866b4e8 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"Ina-unlock ang SIM…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Mag-type ng PIN na 4 hanggang 8 numero."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"Dapat ay 8 numero o higit pa ang PUK code."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukan ulit pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Mali ang PIN code ng SIM, dapat ka nang makipag-ugnayan sa iyong carrier upang i-unlock ang iyong device."</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index a2268ef6cfff..ff0bc9a867e6 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"SIM\'in kilidi açılıyor…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"4 ila 8 haneli bir PIN yazın."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK kodu 8 veya daha çok basamaklı bir sayı olmalıdır."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye sonra tekrar deneyin."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Şifrenizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Yanlış SIM PIN kodu. Cihazınızın kilidini açmak için artık operatörünüzle bağlantı kurmanız gerekiyor."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 596e47768444..dc6ef4dc9ac0 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -98,7 +98,7 @@
<string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"‏SIM کو غیر مقفل کیا جا رہا ہے…"</string>
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"‏ایسا PIN ٹائپ کریں جو 4 تا 8 اعداد پر مشتمل ہو۔"</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"‏PUK کوڈ 8 یا زائد اعداد پر مشتمل ہونا چاہیے۔"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"‏آپ نے اپنا PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"‏آپ نے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اپنا PIN غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"آپ نے اپنا پاس ورڈ <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏غلط SIM PIN کوڈ، اب آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔"</string>
diff --git a/packages/SystemUI/res-keyguard/values/integers.xml b/packages/SystemUI/res-keyguard/values/integers.xml
index c6e90c0fcdec..b08fde339d65 100644
--- a/packages/SystemUI/res-keyguard/values/integers.xml
+++ b/packages/SystemUI/res-keyguard/values/integers.xml
@@ -27,4 +27,7 @@
0x50 = bottom, 0x01 = center_horizontal -->
<integer name="keyguard_host_view_one_handed_gravity">0x51</integer>
+
+ <!-- Invisibility to use for the date & weather view when it is disabled by a clock -->
+ <integer name="keyguard_date_weather_view_invisibility">4</integer>
</resources>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index a3a7135dabad..66c57fc2a9ac 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -23,7 +23,7 @@
android:outlineProvider="none" >
<LinearLayout
- android:id="@+id/keyguard_indication_area"
+ android:id="@id/keyguard_indication_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
@@ -31,7 +31,7 @@
android:orientation="vertical">
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
- android:id="@+id/keyguard_indication_text"
+ android:id="@id/keyguard_indication_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
@@ -41,13 +41,12 @@
android:accessibilityLiveRegion="polite"/>
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
- android:id="@+id/keyguard_indication_text_bottom"
+ android:id="@id/keyguard_indication_text_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
- android:minHeight="48dp"
+ android:minHeight="@dimen/keyguard_indication_text_min_height"
android:layout_gravity="center_horizontal"
- android:layout_centerHorizontal="true"
android:paddingStart="@dimen/keyguard_indication_text_padding"
android:paddingEnd="@dimen/keyguard_indication_text_padding"
android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
index 054193a5b323..a595566ef817 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -65,6 +65,8 @@
<TextView
android:id="@+id/volume_value"
android:animateLayoutChanges="true"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -75,6 +77,8 @@
<TextView
android:id="@+id/title"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
diff --git a/packages/SystemUI/res/layout/scene_window_root.xml b/packages/SystemUI/res/layout/scene_window_root.xml
new file mode 100644
index 000000000000..0dcd15b429c1
--- /dev/null
+++ b/packages/SystemUI/res/layout/scene_window_root.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- The root view of the scene window. -->
+<com.android.systemui.scene.ui.view.SceneWindowRootView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/scene_window_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
+
+ <include layout="@layout/super_notification_shade"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</com.android.systemui.scene.ui.view.SceneWindowRootView>
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 0d86e0a40b6d..ab522a388735 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -36,7 +36,7 @@
android:layout_width="@dimen/screenrecord_logo_size"
android:layout_height="@dimen/screenrecord_logo_size"
android:src="@drawable/ic_media_projection_permission"
- android:tint="?androidprv:attr/colorAccentPrimary"
+ android:tint="?androidprv:attr/colorAccentPrimaryVariant"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/screen_share_dialog_title"
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index d9fe949bb327..6601e63fa034 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -21,6 +21,7 @@
<com.android.systemui.shade.NotificationShadeWindowView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/legacy_window_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
@@ -69,6 +70,12 @@
android:layout_height="match_parent"
android:visibility="invisible" />
+ <!-- Root for all keyguard content. It was previously located within the shade. -->
+ <com.android.systemui.keyguard.ui.view.KeyguardRootView
+ android:id="@id/keyguard_root_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
<include layout="@layout/brightness_mirror_container" />
<com.android.systemui.scrim.ScrimView
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
index a8febe79acae..efdb0a360031 100644
--- a/packages/SystemUI/res/layout/window_magnification_settings_view.xml
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -147,10 +147,12 @@
android:id="@+id/magnifier_zoom_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:max="6"
app:progress="0"
app:iconStartContentDescription="@string/accessibility_control_zoom_out"
- app:iconEndContentDescription="@string/accessibility_control_zoom_in"/>
+ app:iconEndContentDescription="@string/accessibility_control_zoom_in"
+ app:tickMark="@android:color/transparent"
+ app:seekBarChangeMagnitude="10"
+ />
<Button
android:id="@+id/magnifier_done_button"
diff --git a/packages/SystemUI/res/raw/fingerprint_dialogue_unlocked_to_checkmark_success_lottie.json b/packages/SystemUI/res/raw/fingerprint_dialogue_unlocked_to_checkmark_success_lottie.json
new file mode 100644
index 000000000000..b1d6a270bc67
--- /dev/null
+++ b/packages/SystemUI/res/raw/fingerprint_dialogue_unlocked_to_checkmark_success_lottie.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":55,"w":80,"h":80,"nm":"unlocked_to_checkmark_success","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".colorAccentPrimary","cl":"colorAccentPrimary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[47.143,32,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[2.761,0],[0,-2.7],[0,0]],"o":[[0,0],[0,-2.7],[-2.761,0],[0,0],[0,0]],"v":[[5,5],[5,-0.111],[0,-5],[-5,-0.111],[-5.01,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.827450990677,0.890196084976,0.992156863213,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":10,"s":[0]}],"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":85,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".colorAccentPrimary","cl":"colorAccentPrimary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38,45,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.827450990677,0.890196084976,0.992156863213,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":10,"s":[0]}],"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":85,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".colorAccentPrimary","cl":"colorAccentPrimary","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[37.999,44.999,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.42,0],[0,1.42],[1.42,0],[0,-1.42]],"o":[[1.42,0],[0,-1.42],[-1.42,0],[0,1.42]],"v":[[0,2.571],[2.571,0],[0,-2.571],[-2.571,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.827450990677,0.890196084976,0.992156863213,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":10,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":85,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".green200","cl":"green200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40.5,40.75,0],"ix":2,"l":2},"a":{"a":0,"k":[12.5,-6.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":10,"s":[60,60,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":19,"s":[112,112,100]},{"t":30,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-10.556,-9.889],[7.444,6.555],[34.597,-20.486]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823529412,0.854901960784,0.709803921569,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":10,"s":[0]},{"t":20,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":10,"op":910,"st":10,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green200","cl":"green200","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":15,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2,"l":2},"a":{"a":0,"k":[40.25,40.25,0],"ix":1,"l":2},"s":{"a":0,"k":[93.5,93.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.12,0],[0,-22.08],[-22.08,0],[0,22.08]],"o":[[-22.08,0],[0,22.08],[22.12,0],[0,-22.08]],"v":[[-0.04,-40],[-40,0],[-0.04,40],[40,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[40.25,40.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823529412,0.854901960784,0.709803921569,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":15,"s":[100]}],"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"t":20,"s":[4]}],"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":10,"op":77,"st":10,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey700","cl":"grey700","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2,"l":2},"a":{"a":0,"k":[40.25,40.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.12,0],[0,-22.08],[-22.08,0],[0,22.08]],"o":[[-22.08,0],[0,22.08],[22.12,0],[0,-22.08]],"v":[[-0.04,-40],[-40,0],[-0.04,40],[40,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.278431385756,0.278431385756,0.278431385756,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"t":20,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[40.25,40.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 70d4cd0f5e4b..cd22df49a012 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deel"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Skermopname is gestoor"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekyk"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Kon nie skermopname uitvee nie"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Kon nie skermopname stoor nie"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Terug"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Tuis"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesig is gestaaf"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestig"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestig om te voltooi"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontsluit met gesig. Druk die ontsluitikoon om voort te gaan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Ontsluit met gesig."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Vergroot die hele skerm"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Vergroot \'n deel van die skerm"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Maak vergrotinginstellings oop"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Maak vergrotinginstellings toe"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Sleep hoek om grootte te verander"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Laat diagonale rollees toe"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Verander grootte"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> speel tans vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Speel"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Onderbreek"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Vorige snit"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent luister"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Neem notas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index b484d8bd7a3e..dfba9432ce50 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"የማያ ገፅ ቀረጻ ተቀምጧል"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገፅ ቀረጻን መሰረዝ ላይ ስህተት"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"የማያ ገጽ ቀረጻን ማስቀመጥ ላይ ስህተት"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገፅ ቀረጻን መጀመር ላይ ስህተት"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ተመለስ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"መነሻ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"መልክ ተረጋግጧል"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ተረጋግጧል"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"በመልክ ተከፍቷል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"በመልክ ተከፍቷል።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገፅ እይታን ያጉሉ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"የማጉያ ቅንብሮችን ክፈት"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"የማጉላት ቅንብሮችን ዝጋ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"መጠን ለመቀየር ጠርዙን ይዘው ይጎትቱ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ሰያፍ ሽብለላን ፍቀድ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"መጠን ቀይር"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> እየተጫወተ ነው"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ከ<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> እያሄደ ነው"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"አጫውት"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ላፍታ አቁም"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ቀዳሚ ትራክ"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ረዳት በማዳመጥ ላይ ነው"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ማሳወቂያ}one{# ማሳወቂያዎች}other{# ማሳወቂያዎች}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>፣ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index bc4ec878e664..a19386b5d960 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"مشاركة"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"تم حفظ تسجيل الشاشة"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"انقر لعرض التسجيل."</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"حدث خطأ أثناء حفظ تسجيل محتوى الشاشة."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
<string name="accessibility_back" msgid="6530104400086152611">"رجوع"</string>
<string name="accessibility_home" msgid="5430449841237966217">"الرئيسية"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"تمّت مصادقة الوجه."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"تم فتح القفل بالتعرّف على وجهك. للمتابعة، اضغط على رمز فتح القفل."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"تم فتح قفل جهازك عند تقريبه من وجهك."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
@@ -280,7 +280,7 @@
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"جارٍ التفعيل…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"توفير البيانات مفعّل"</string>
<string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{جهاز واحد}zero{# جهاز}two{جهازان}few{# أجهزة}many{# جهازًا}other{# جهاز}}"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"الفلاش"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ضوء الفلاش"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"الكاميرا قيد الاستخدام"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"بيانات الجوّال"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"استخدام البيانات"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"تكبير الشاشة كلها"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"تكبير جزء من الشاشة"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"فتح إعدادات التكبير"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"إغلاق إعدادات التكبير"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"اسحب الزاوية لتغيير الحجم."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"السماح بالتمرير القطري"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغيير الحجم"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"يتم تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> من إجمالي <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" قيد التشغيل"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"تشغيل"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"إيقاف مؤقت"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"المقطع الصوتي السابق"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‏يستمع \"مساعد Google\" إليك الآن."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}other{# إشعار}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"تدوين الملاحظات"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index e69fa1663a57..5d4e8961be41 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"শ্বেয়াৰ কৰক"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্ৰীন ৰেকৰ্ডিং ছেভ কৰা হ’ল"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"চাবলৈ টিপক"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রীন ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ৰেকৰ্ড কৰা স্ক্ৰীন ছেভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
<string name="accessibility_back" msgid="6530104400086152611">"উভতি যাওক"</string>
<string name="accessibility_home" msgid="5430449841237966217">"গৃহ পৃষ্ঠাৰ বুটাম"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"নিশ্চিত কৰিলে"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"পূৰ্ণ স্ক্ৰীন বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্ৰীনৰ কিছু অংশ বিবৰ্ধন কৰক"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"বিবৰ্ধন কৰাৰ ছেটিং খোলক"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"বিবৰ্ধনৰ ছেটিং বন্ধ কৰক"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"আকাৰ সলনি কৰিবলৈ চুককেইটা টানি আনি এৰক"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কোণীয়াকৈ স্ক্ৰ’ল কৰাৰ অনুমতি দিয়ক"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"আকাৰ সলনি কৰক"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিং"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ হৈ আছে"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ৰ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> চলি আছে"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"প্লে’ কৰক"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"পজ কৰক"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"পূৰ্বৱৰ্তী ট্ৰেক"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistantএ শুনি আছে"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# টা জাননী}one{# টা জাননী}other{# টা জাননী}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"টোকাগ্ৰহণ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"আপোনাৰ ষ্টাইলাছ এটা চাৰ্জাৰৰ সৈতে সংযোগ কৰক"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"ষ্টাইলাছৰ বেটাৰী কম আছে"</string>
<string name="video_camera" msgid="7654002575156149298">"ভিডিঅ’ কেমেৰা"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ব্যক্তিগত এপৰ পৰা বাৰ্তা পঠিয়াব নোৱাৰি"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা কল কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"কাম সম্পৰ্কীয় এটা ফ’ন এপ্ ইনষ্টল কৰক"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"বাতিল কৰক"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"লক স্ক্ৰীন কাষ্টমাইজ কৰক"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"লক স্ক্ৰীন কাষ্টমাইজ কৰিবলৈ আনলক কৰক"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ৱাই-ফাই উপলব্ধ নহয়"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 740d5f0d43ce..0107268a4692 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaşın"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran çəkilişi yadda saxlanıldı"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Baxmaq üçün toxunun"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran çəkimini yadda saxlayarkən xəta oldu"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ana səhifə"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Üz doğrulandı"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Təsdiqləndi"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb davam edin."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Üz ilə kiliddən çıxarılıb."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekranı böyüdün"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran hissəsinin böyüdülməsi"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Böyütmə ayarlarını açın"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Böyütmə ayarlarını bağlayın"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Ölçüsünü dəyişmək üçün küncündən sürüşdürün"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diaqonal sürüşdürməyə icazə verin"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ölçüsünü dəyişin"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudulur"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> işləyir"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Oxudun"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Durdurun"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Əvvəlki trek"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent dinləyir"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Qeyd tutma"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f4b9e373751b..173a8fb08f0c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška pri čuvanju snimka ekrana"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano je licem. Pritisnite ikonu otključavanja za nastavak"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Otključano je licem."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
@@ -209,7 +209,7 @@
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Prozor sa obaveštenjima."</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brza podešavanja."</string>
<string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brza podešavanja i traka sa obaveštenjima."</string>
- <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
+ <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran"</string>
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran za posao"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
@@ -784,7 +784,7 @@
<string name="tuner_right" msgid="8247571132790812149">"Strelica udesno"</string>
<string name="tuner_menu" msgid="363690665924769420">"Meni"</string>
<string name="tuner_app" msgid="6949280415826686972">"Aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="notification_channel_alerts" msgid="3385787053375150046">"Obaveštenja"</string>
+ <string name="notification_channel_alerts" msgid="3385787053375150046">"Upozorenja"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimci ekrana"</string>
<string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori podešavanja uvećanja"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zatvori podešavanja uvećanja"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Prevucite ugao da biste promenili veličinu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno skrolovanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promeni veličinu"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Pusti"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna pesma"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pomoćnik sluša"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pravljenje beležaka"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 8ef6510648aa..918372e027bb 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Абагуліць"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Запіс экрана захаваны"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Націсніце для прагляду"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Памылка выдалення запісу экрана"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Памылка захавання запісу экрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"На Галоўную старонку"</string>
@@ -142,7 +142,8 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Твар распазнаны"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Пацверджана"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+ <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+ <skip />
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
@@ -859,6 +860,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Павялічыць увесь экран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Павялічыць частку экрана"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Адкрыць налады павелічэння"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Закрыць налады павелічэння"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Каб змяніць памер, перацягніце вугал"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дазволіць прагортванне па дыяганалі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змяніць памер"</string>
@@ -943,6 +945,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"У праграме \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\" прайграецца кампазіцыя \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Прайграць"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Прыпыніць"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Папярэдні трэк"</string>
@@ -1106,7 +1109,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Памочнік слухае"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}other{# апавяшчэння}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Стварэнне нататак"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 5291e09750f7..841dc6e595b3 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Записът е запазен"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при запазването на записа на екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Начало"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е удостоверено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потвърдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Докоснете „Потвърждаване“ за завършване"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отключено с лице. Натиснете иконата за отключване, за да продължите."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Отключено с лице."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличаване на целия екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличаване на част от екрана"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Отваряне на настройките за увеличението"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Затваряне на настройките за увеличение"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Плъзнете ъгъла за преоразмеряване"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешаване на диагонално превъртане"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Преоразмеряване"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се възпроизвежда от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> от <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Пускане"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Пауза"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Предишен запис"</string>
@@ -1055,7 +1057,7 @@
<string name="mobile_data_connection_active" msgid="944490013299018227">"Свързано"</string>
<string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Установена е временна връзка"</string>
<string name="mobile_data_poor_connection" msgid="819617772268371434">"Слаба връзка"</string>
- <string name="mobile_data_off_summary" msgid="3663995422004150567">"Връзката за мобилни данни няма да е автоматична"</string>
+ <string name="mobile_data_off_summary" msgid="3663995422004150567">"Връзката за мобилни данни няма да е автом."</string>
<string name="mobile_data_no_connection" msgid="1713872434869947377">"Няма връзка"</string>
<string name="non_carrier_network_unavailable" msgid="770049357024492372">"Няма други налични мрежи"</string>
<string name="all_network_unavailable" msgid="4112774339909373349">"Няма налични мрежи"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Асистент слуша"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}other{# известия}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Водене на бележки"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 1b1c6fdc7b4b..f2404faa7f34 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"শেয়ার করুন"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"দেখতে ট্যাপ করুন"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"স্ক্রিন রেকর্ডিং সেভ করার সময় কোনও সমস্যা হয়েছে"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ফিরুন"</string>
<string name="accessibility_home" msgid="5430449841237966217">"হোম"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ফেস যাচাই করা হয়েছে"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যাওয়ার জন্য আনলক আইকনে প্রেস করুন।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ফেসের সাহায্যে আনলক করা হয়েছে।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"সম্পূর্ণ স্ক্রিন বড় করে দেখা"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"বড় করে দেখার সেটিংস খুলুন"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"\'বড় করে দেখা\' সেটিংস বন্ধ করুন"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ছোট বড় করার জন্য কোণ টেনে আনুন"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কোনাকুনি স্ক্রল করার অনুমতি দেওয়া"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ছোট বড় করা"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>টির মধ্যে <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>টি"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> চলছে"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"চালান"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"পজ করুন"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"আগের ট্র্যাক"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant শুনছে"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ব্রডকাস্ট করা হচ্ছে"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"কোনও চার্জারের সাথে আপনার স্টাইলাস কানেক্ট করুন"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"স্টাইলাস ব্যাটারিতে চার্জ কম আছে"</string>
<string name="video_camera" msgid="7654002575156149298">"ভিডিও ক্যামেরা"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ব্যক্তিগত অ্যাপ থেকে কল করা যাবে না"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে কল করার অনুমতি দেয়"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"একটি অফিসের ফোন অ্যাপ ইনস্টল করুন"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"বাতিল করুন"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"লক স্ক্রিন কাস্টমাইজ করুন"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"লক স্ক্রিন কাস্টমাইজ করতে আনলক করুন"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ওয়াই-ফাই উপলভ্য নয়"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b686633b54fe..0f4f0358404a 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da vidite"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Greška prilikom brisanja snimka ekrana"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška prilikom pohranjivanja snimka ekrana"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Dugme za početnu stranicu"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je provjereno"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da završite"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano licem. Pritisnite ikonu za otklj. da nastavite."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Otključano je licem."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećavanje prikaza preko cijelog ekrana"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećavanje dijela ekrana"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori postavke uvećavanja"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zatvori postavke uvećavanja"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Prevucite ugao da promijenite veličinu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno klizanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promijeni veličinu"</string>
@@ -905,7 +906,7 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonite iz omiljenog"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Premjesti na poziciju <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string>
- <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Odaberite kontrole uređaja da pristupite brzo"</string>
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Odaberite kontrole uređaja za brzi pristup"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite i prevucite da preuredite kontrole"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promjene nisu sačuvane"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Pjesma <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se reproducira pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproduciranje"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziranje"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna numera"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent sluša"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pisanje bilješki"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
@@ -1142,11 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Baterija pisaljke je slaba"</string>
<string name="video_camera" msgid="7654002575156149298">"Video kamera"</string>
- <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ne možete upućivati pozive iz osobne aplikacije"</string>
- <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizacija dopušta upućivanje poziva samo iz poslovnih aplikacija"</string>
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nije moguće pozvati iz lične aplikacije"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizacija vam dozvoljava da upućujete pozive samo iz poslovnih aplikacija"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
- <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instaliraj poslovnu aplikaciju telefona"</string>
- <string name="call_from_work_profile_close" msgid="5830072964434474143">"Odustani"</string>
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalirajte poslovnu aplikaciju za telefon"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Otkaži"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje ekrana"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da prilagodite zaključavanje ekrana"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi mreža nije dostupna"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 965f4571b463..a02363e1bfcb 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"S\'ha desat la gravació de pantalla"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"S\'ha produït un error en desar la gravació de la pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Enrere"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Inici"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirma per completar"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"S\'ha desbloquejat amb la cara. Prem la icona per continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"S\'ha desbloquejat amb la cara."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Amplia la pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplia una part de la pantalla"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Obre la configuració de l\'ampliació"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Tanca la configuració de l\'ampliació"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrossega el cantó per canviar la mida"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permet el desplaçament en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Canvia la mida"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) s\'està reproduint des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reprodueix"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Posa en pausa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'assistent t\'escolta"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}many{# notificacions}other{# notificacions}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Presa de notes"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 80afe6039192..c2b7c544230d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky se uložila"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Klepnutím nahrávku zobrazíte"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Při ukládání záznamu obrazovky došlo k chybě"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Zpět"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Domů"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Obličej byl ověřen"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrzeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ověření dokončíte klepnutím na Potvrdit"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Odemknuto obličejem."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zvětšit celou obrazovku"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zvětšit část obrazovky"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otevřít nastavení zvětšení"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zavřít nastavení zvětšení"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Velikost změníte přetažením rohu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povolit diagonální posouvání"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Změnit velikost"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> hrajte z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je spuštěna"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Přehrát"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pozastavit"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Předchozí skladba"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent poslouchá"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g> <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Poznámky"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7a6119fb38ec..53c15e16c829 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Skærmoptagelsen er gemt"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tryk for at se"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Skærmoptagelsen kunne ikke gemmes"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tilbage"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Hjem"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansigtet er godkendt"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekræftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tryk på Bekræft for at udføre"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at fortsætte."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Låst op ved hjælp af ansigt."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstør hele skærmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstør en del af skærmen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Åbn indstillinger for forstørrelse"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Luk indstillinger for forstørrelse"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Træk i hjørnet for at justere størrelsen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillad diagonal rulning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Juster"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspilles via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Afspil"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Sæt på pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Afspil forrige"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google Assistent lytter med"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikation}one{# notifikation}other{# notifikationer}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetagning"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Udsender"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop udsendelsen <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4bff28c156de..13a6fab2e229 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Teilen"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Bildschirmaufzeichnung gespeichert"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Zum Ansehen tippen"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Fehler beim Speichern der Bildschirmaufzeichnung"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Zurück"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startbildschirm"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesicht authentifiziert"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bestätigt"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Per Gesichtserkennung entsperrt. Tippe auf das Symbol „Entsperren“, um fortzufahren."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Gerät per Gesichtserkennung entsperrt."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
@@ -243,7 +243,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Eingabe"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hörhilfen"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hörgeräte"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Wird aktiviert…"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. drehen"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ganzen Bildschirm vergrößern"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Vergrößerungseinstellungen öffnen"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Vergrößerungseinstellungen schließen"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Zum Anpassen der Größe Ecke ziehen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonales Scrollen erlauben"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Größe ändern"</string>
@@ -896,8 +897,8 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> hinzufügen?"</string>
- <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> darf auswählen, welche Einstellungen und Inhalte hier angezeigt werden."</string>
- <string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Einstellungen für <xliff:g id="APPNAME">%s</xliff:g> entfernen?"</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> darf auswählen, welche Steuerelemente und Inhalte hier angezeigt werden."</string>
+ <string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Steuerelemente für <xliff:g id="APPNAME">%s</xliff:g> entfernen?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Aus Favoriten entfernt"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> von <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Wiedergeben"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausieren"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Vorheriger Titel"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant hört zu"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notizen machen"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 9d9638a53a25..32f3ff64f0b1 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Κοινοποίηση"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Η εγγραφή οθόνης αποθηκεύτηκε"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Πατήστε για προβολή"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Σφάλμα κατά την αποθήκευση της εγγραφής οθόνης"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Πίσω"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Αρχική οθόνη"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Επιβεβαιώθηκε"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Ξεκλειδώθηκε με αναγνώριση προσώπου."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Μεγέθυνση πλήρους οθόνης"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Μεγέθυνση μέρους της οθόνης"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Άνοιγμα ρυθμίσεων μεγιστοποίησης"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Κλείσιμο ρυθμίσεων μεγιστοποίησης"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Σύρετε τη γωνία για αλλαγή μεγέθους"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Να επιτρέπεται η διαγώνια κύλιση"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Αλλαγή μεγέθους"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Γίνεται αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> από <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Αναπαραγωγή"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Παύση"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Προηγούμενο κομμάτι"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Ο Βοηθός ακούει"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Δημιουργία σημειώσεων"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Μετάδοση"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Διακοπή μετάδοσης με την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 0965fe35f909..d613f4c80d10 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Unlocked by face."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -243,7 +243,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing Aids"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Open magnification settings"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Close magnification settings"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Drag corner to resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 3b6899a63167..3af0ca9c6a0f 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Unlocked by face."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Open magnification settings"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Close magnification settings"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Drag corner to resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1106,7 +1108,8 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string>
+ <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 0965fe35f909..d613f4c80d10 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Unlocked by face."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -243,7 +243,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing Aids"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Open magnification settings"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Close magnification settings"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Drag corner to resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 0965fe35f909..d613f4c80d10 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Unlocked by face."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -243,7 +243,7 @@
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing Aids"</string>
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Magnify full screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Magnify part of screen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Open magnification settings"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Close magnification settings"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Drag corner to resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Allow diagonal scrolling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Resize"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 3f2b17199a12..457a8c22b511 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎Share‎‏‎‎‏‎"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎Screen recording saved‎‏‎‎‏‎"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Tap to view‎‏‎‎‏‎"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎Error deleting screen recording‎‏‎‎‏‎"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎Error saving screen recording‎‏‎‎‏‎"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎"</string>
<string name="accessibility_back" msgid="6530104400086152611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎Back‎‏‎‎‏‎"</string>
<string name="accessibility_home" msgid="5430449841237966217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎Home‎‏‎‎‏‎"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎Face authenticated‎‏‎‎‏‎"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎Confirmed‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎Unlocked by face. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎Unlocked by face.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎Unlocked by face. Press to continue.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎Face recognized. Press to continue.‎‏‎‎‏‎"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎Magnify full screen‎‏‎‎‏‎"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎Magnify part of screen‎‏‎‎‏‎"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎Open magnification settings‎‏‎‎‏‎"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎Close magnification settings‎‏‎‎‏‎"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎Drag corner to resize‎‏‎‎‏‎"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎Allow diagonal scrolling‎‏‎‎‏‎"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎Resize‎‏‎‎‏‎"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Settings‎‏‎‎‏‎"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SONG_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ by ‎‏‎‎‏‏‎<xliff:g id="ARTIST_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ is playing from ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="TOTAL_TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is running‎‏‎‎‏‎"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎Play‎‏‎‎‏‎"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎Pause‎‏‎‎‏‎"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎Previous track‎‏‎‎‏‎"</string>
@@ -1106,7 +1108,8 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎Assistant is listening‎‏‎‎‏‎"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="TEMPERATURE">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎Notetaking‎‏‎‎‏‎"</string>
+ <string name="note_task_button_label" msgid="230135078402003532">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎Note-taking‎‏‎‎‏‎"</string>
+ <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎Note-taking, ‎‏‎‎‏‏‎<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎Broadcasting‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎Stop broadcasting ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎If you broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ or change the output, your current broadcast will stop‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d175e661e7b9..226bd0d074e7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Se guardó la grabación de pantalla"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Presiona para ver"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se pudo borrar la grabación de pantalla"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Se produjo un error al guardar la grabación de pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página principal"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Se autenticó el rostro"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Presiona Confirmar para completar"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueo con rostro. Presiona ícono desbl. para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Se desbloqueó con rostro."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
@@ -269,7 +269,7 @@
<string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string>
<string name="quick_settings_inversion_label" msgid="3501527749494755688">"Invertir colores"</string>
<string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corregir colores"</string>
- <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamaño de la fuente"</string>
+ <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamaño de fuente"</string>
<string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrar usuarios"</string>
<string name="quick_settings_done" msgid="2163641301648855793">"Listo"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Cerrar"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir la configuración de ampliación"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Cerrar configuración de ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastra la esquina para cambiar el tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Desplazamiento en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -905,7 +906,7 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"quitar de favoritos"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Mover a la posición <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Controles"</string>
- <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Elige los controles de dispositivos para acceso rápido"</string>
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Elige los controles de dispositivos a los que quieres acceder rápido"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén presionado y arrastra un control para reubicarlo"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Se quitaron todos los controles"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"No se guardaron los cambios"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistente está escuchando"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 31d451eb4bdb..d16c78902587 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Grabación de pantalla guardada"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para verla"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se ha podido eliminar la grabación de la pantalla"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"No se ha podido guardar la grabación de pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Inicio"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar la acción"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado con la cara. Toca el icono de desbloquear para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Desbloqueado con la cara."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir ajustes de ampliación"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Cerrar ajustes de ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastra la esquina para cambiar el tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir ir en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Canción anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"El Asistente está escuchando"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 7d017927e588..cf3fa34c91a0 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,7 +103,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Salvestamise ajal on Androidil juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Rakenduse salvestamise ajal on Androidil juurdepääs kõigele, mis on selles rakenduses nähtaval või mida selles esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Alusta salvestamist"</string>
- <string name="screenrecord_audio_label" msgid="6183558856175159629">"Heli salvestamine"</string>
+ <string name="screenrecord_audio_label" msgid="6183558856175159629">"Salvesta heli"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Seadme heli"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Seadmest pärinev heli, nt muusika, kõned ja helinad"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaga"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekraanisalvestis on salvestatud"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Puudutage kuvamiseks"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Viga ekraanikuva salvestise kustutamisel"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Viga ekraanisalvestise salvestamisel"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tagasi"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Kodu"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Nägu on autenditud"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kinnitatud"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avati näoga. Jätkamiseks vajutage avamise ikooni."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Avati näoga."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Täisekraani suurendamine"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekraanikuva osa suurendamine"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ava suurendamisseaded"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Sule suurendamisseaded"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Suuruse muutmiseks lohistage nurka"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Luba diagonaalne kerimine"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuda suurust"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> esitatakse rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> töötab"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Esita"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Peata"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Eelmine lugu"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent kuulab"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Märkmete tegemine"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ühendage elektronpliiats laadijaga"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Elektronpliiatsi akutase on madal"</string>
<string name="video_camera" msgid="7654002575156149298">"Videokaamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Isiklikust rakendusest ei saa helistada"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Teie organisatsioon lubab helistada ainult töörakendustest."</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"• Installige töö telefonirakendus"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Tühista"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Kohanda lukustuskuva"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lukustuskuva kohandamiseks avage"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi pole saadaval"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index ca6d85a8caf1..2e9254bb4b15 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partekatu"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gorde da pantailaren grabaketa"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Sakatu ikusteko"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore bat gertatu da pantaila-grabaketa gordetzean"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atzera"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Hasiera"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autentifikatu da aurpegia"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Aurpegiaren bidez desblokeatu da. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Aurpegiaren bidez desblokeatu da."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Handitu pantaila osoa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Handitu pantailaren zati bat"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ireki luparen ezarpenak"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Itxi luparen ezarpenak"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastatu izkina bat tamaina aldatzeko"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Eman diagonalki gora eta behera egiteko aukera erabiltzeko baimena"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Aldatu tamaina"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) ari da erreproduzitzen <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> abian da"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Erreproduzitu"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausatu"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Aurrekoa"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Laguntzailea entzuten ari da"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Oharrak idaztea"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Konektatu arkatza kargagailu batera"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Arkatzak bateria gutxi du"</string>
<string name="video_camera" msgid="7654002575156149298">"Bideokamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ezin duzu deitu aplikazio pertsonaletatik"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Laneko aplikazioetatik soilik deitzeko baimena ematen du zure erakundeak"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalatu telefonoetarako aplikazio bat (lanerako)"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Utzi"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Pertsonalizatu pantaila blokeatua"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desblokeatu eta pertsonalizatu pantaila blokeatua"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi-konexioa ez dago erabilgarri"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index c9f2d6f20ff6..d550c6d42866 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -69,7 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"‏فعال کردن USB"</string>
<string name="learn_more" msgid="4690632085667273811">"بیشتر بدانید"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"نماگرفت"</string>
- <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‏Extend Unlock غیرفعال شده است"</string>
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"«تمدید حالت باز» غیرفعال شده است"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"تصویری ارسال کرد"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"درحال ذخیره نماگرفت…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"درحال ذخیره کردن نماگرفت در نمایه کاری…"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"هم‌رسانی"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبط‌شده از صفحه‌نمایش ذخیره شد"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"خطا در حذف فایل ضبط صفحه‌نمایش"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیره‌سازی ضبط صفحه‌نمایش"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحه‌نمایش"</string>
<string name="accessibility_back" msgid="6530104400086152611">"برگشت"</string>
<string name="accessibility_home" msgid="5430449841237966217">"صفحهٔ اصلی"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالت‌سنجی شد"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"قفلْ با چهره باز شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"قفل با چهره باز شد."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"درشت‌نمایی تمام‌صفحه"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"درشت‌نمایی بخشی از صفحه"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"باز کردن تنظیمات درشت‌نمایی"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"بستن تنظیمات درشت‌نمایی"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"برای تغییر اندازه، گوشه را بکشید"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"اجازه دادن برای پیمایش قطری"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغییر اندازه"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش می‌شود"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا است"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"پخش"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"توقف موقت"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"آهنگ قبلی"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"«دستیار» درحال گوش کردن است"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اعلان}one{# اعلان}other{# اعلان}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"یادداشت‌برداری"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همه‌فرستی"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همه‌فرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همه‌فرستی کنید یا خروجی را تغییر دهید، همه‌فرستی کنونی متوقف خواهد شد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 26dbaf592f5e..88aa8b22612a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Jaa"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Näyttötallenne tallennettu"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Napauta näyttääksesi"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Virhe poistettaessa näyttötallennetta"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Virhe näyttötallenteen tallentamisessa"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Takaisin"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Aloitus"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Kasvot tunnistettu"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Vahvistettu"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Valitse lopuksi Vahvista"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Avattu kasvojen avulla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Koko näytön suurennus"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Suurenna osa näytöstä"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Avaa suurennusasetukset"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Sulje suurennusasetukset"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Muuta kokoa vetämällä kulmaa"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Salli diagonaalinen vierittäminen"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuta kokoa"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Toista"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Keskeytä"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Edellinen kappale"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant kuuntelee"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Muistiinpanojen tekeminen"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e87c6a36a03f..4e85a84a7d37 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -96,25 +96,19 @@
<string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
<string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applications ouvertes ont détecté cette capture d\'écran."</string>
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à une note"</string>
- <!-- no translation found for screenrecord_title (4257171601439507792) -->
- <skip />
+ <string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
- <!-- no translation found for screenrecord_permission_dialog_title (303380743267672953) -->
- <skip />
- <!-- no translation found for screenrecord_permission_dialog_warning_entire_screen (4152602778470789965) -->
- <skip />
- <!-- no translation found for screenrecord_permission_dialog_warning_single_app (6818309727772146138) -->
- <skip />
- <!-- no translation found for screenrecord_permission_dialog_continue (5811122652514424967) -->
- <skip />
+ <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Commencer l\'enregistrement?"</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Pendant l\'enregistrement, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une application, Android a accès à tout ce qui est visible ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Commencer l\'enregistrement"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Enregistrer des fichiers audio"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio de l\'appareil"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sons de l\'appareil comme la musique, les appels et les sonneries"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Microphone"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio de l\'appareil et du microphone"</string>
- <!-- no translation found for screenrecord_continue (4055347133700593164) -->
- <skip />
+ <string name="screenrecord_continue" msgid="4055347133700593164">"Commencer"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Enregistrement de l\'écran"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Enregistrement de l\'écran et de l\'audio"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les endroits touchés à l\'écran"</string>
@@ -122,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement sauvegardé"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Touchez pour afficher"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur d\'enregistrement de l\'écran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Précédent"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Domicile"</string>
@@ -148,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Touchez Confirmer pour terminer"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverr. par reconn. faciale. App. sur l\'icône pour continuer."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Déverrouillé avec le visage."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverr. par reconnaissance faciale. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
@@ -171,34 +165,20 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous entrez un schéma incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous entrez un NIP incorrect à la prochaine tentative, votre profil professionnel et ses données seront supprimés."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous entrez un mot de passe incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
- <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
- <skip />
- <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
- <skip />
- <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
- <skip />
- <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
- <skip />
- <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
- <skip />
- <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
- <skip />
- <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
- <skip />
- <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
- <skip />
- <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
- <skip />
- <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
- <skip />
- <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
- <skip />
- <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
- <skip />
- <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
- <skip />
- <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
- <skip />
+ <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Configuration"</string>
+ <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Plus tard"</string>
+ <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Cela est requis pour améliorer la sécurité et la performance"</string>
+ <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
+ <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Déverrouillage par empreinte digitale"</string>
+ <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configurer le Déverrouillage par empreinte digitale"</string>
+ <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Pour configurer le Déverrouillage par empreinte digitale à nouveau, les images et les modèles actuels de votre empreinte digitale devront être supprimés.\n\nAprès cela, vous devrez configurer le Déverrouillage par empreinte digitale à nouveau pour utiliser votre empreinte digitale afin de déverrouiller votre téléphone."</string>
+ <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Pour configurer le Déverrouillage par empreinte digitale à nouveau, les images et les modèles actuels de votre empreinte digitale devront être supprimés.\n\nAprès cela, vous devrez configurer le Déverrouillage par empreinte digitale à nouveau pour utiliser votre empreinte digitale afin de déverrouiller votre téléphone."</string>
+ <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Impossible de configurer le Déverrouillage par empreinte digitale. Accédez au menu Paramètres pour réessayer."</string>
+ <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Configurer le déverrouillage par reconnaissance faciale à nouveau"</string>
+ <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Déverrouillage par reconnaissance faciale"</string>
+ <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Configurer le Déverrouillage par reconnaissance faciale"</string>
+ <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Pour configurer le Déverrouillage par reconnaissance faciale à nouveau, votre modèle facial devra être supprimé.\n\nVous devrez configurer cette fonctionnalité à nouveau pour utiliser votre visage afin de déverrouiller votre téléphone."</string>
+ <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Impossible de configurer le Déverrouillage par reconnaissance faciale. Accédez au menu Paramètres pour réessayer."</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touchez le capteur d\'empreintes digitales"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez plutôt l\'empreinte digitale."</string>
<!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -414,42 +394,24 @@
<string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applications et les données de cet utilisateur seront supprimées."</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"Supprimer"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
- <!-- no translation found for media_projection_dialog_warning (1303664408388363598) -->
- <skip />
- <!-- no translation found for media_projection_sys_service_dialog_title (3751133258891897878) -->
- <skip />
- <!-- no translation found for media_projection_sys_service_dialog_warning (2443872865267330320) -->
- <skip />
- <!-- no translation found for screen_share_permission_dialog_option_entire_screen (3131200488455089620) -->
- <skip />
- <!-- no translation found for screen_share_permission_dialog_option_single_app (4350961814397220929) -->
- <skip />
- <!-- no translation found for screen_share_permission_app_selector_title (1404878013670347899) -->
- <skip />
- <!-- no translation found for media_projection_entry_app_permission_dialog_title (9155535851866407199) -->
- <skip />
- <!-- no translation found for media_projection_entry_app_permission_dialog_warning_entire_screen (8736391633234144237) -->
- <skip />
- <!-- no translation found for media_projection_entry_app_permission_dialog_warning_single_app (5211695779082563959) -->
- <skip />
- <!-- no translation found for media_projection_entry_app_permission_dialog_continue (295463518195075840) -->
- <skip />
- <!-- no translation found for media_projection_entry_cast_permission_dialog_title (8860150223172993547) -->
- <skip />
- <!-- no translation found for media_projection_entry_cast_permission_dialog_warning_entire_screen (1986212276016817231) -->
- <skip />
- <!-- no translation found for media_projection_entry_cast_permission_dialog_warning_single_app (9900961380294292) -->
- <skip />
- <!-- no translation found for media_projection_entry_cast_permission_dialog_continue (7209890669948870042) -->
- <skip />
- <!-- no translation found for media_projection_entry_generic_permission_dialog_title (4519802931547483628) -->
- <skip />
- <!-- no translation found for media_projection_entry_generic_permission_dialog_warning_entire_screen (5407906851409410209) -->
- <skip />
- <!-- no translation found for media_projection_entry_generic_permission_dialog_warning_single_app (3454859977888159495) -->
- <skip />
- <!-- no translation found for media_projection_entry_generic_permission_dialog_continue (8640381403048097116) -->
- <skip />
+ <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information qui est visible sur votre écran ou lue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et les contenus audio que vous faites jouer."</string>
+ <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Commencer à enregistrer ou à diffuser?"</string>
+ <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Le service offrant cette fonction aura accès à toute l\'information qui est visible sur votre écran ou lu sur votre appareil pendant que vous enregistrez ou diffusez. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
+ <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Écran entier"</string>
+ <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule application"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une application"</string>
+ <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou diffusez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une application, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Commencer"</string>
+ <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Commencer la diffusion?"</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Lorsque vous diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Commencer la diffusion"</string>
+ <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Commencer à partager?"</string>
+ <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Lorsque vous partagez, enregistrez ou diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+ <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Commencer"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'application Device Policy"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
@@ -897,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir la totalité de l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ouvrir les paramètres d\'agrandissement"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Fermer les paramètres d\'agrandissement"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Faire glisser le coin pour redimensionner"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser défilement diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
@@ -943,10 +906,9 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"supprimer des favoris"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Déplacer l\'élément à la position <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Commandes"</string>
- <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
- <skip />
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Choisissez les commandes de l\'appareil auxquelles vous souhaitez accéder rapidement"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Faites glisser les commandes pour les réorganiser"</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été retirées"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifications non enregistrées"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applications"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Réorganiser"</string>
@@ -982,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecteur à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Faire jouer"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Interrompre"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Chanson précédente"</string>
@@ -1145,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'Assistant est à l\'écoute"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# de notifications}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Prise de note"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
@@ -1180,16 +1146,12 @@
<string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</string>
- <string name="video_camera" msgid="7654002575156149298">"Mode vidéo"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="video_camera" msgid="7654002575156149298">"Caméra"</string>
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une application personnelle"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une application de téléphone professionnelle"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuler"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Personn. l\'écran de verrouillage"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non accessible"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index ee51853bdc6f..9295b54f303d 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement sauvegardé"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Appuyez pour afficher"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur lors de l\'enregistrement de l\'écran"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Retour"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Accueil"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Appuyez sur \"Confirmer\" pour terminer"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverrouillage par visage. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Déverrouillé par le visage."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir tout l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ouvrir les paramètres d\'agrandissement"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Fermer les paramètres d\'agrandissement"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Faire glisser le coin pour redimensionner"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser le défilement diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sur <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> est en cours d\'exécution"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Lecture"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Titre précédent"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'Assistant écoute"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# notifications}other{# notifications}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Prise de notes"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index f9cf9b3deecd..c4a883eb9c96 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gravación da pantalla gardada"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para ver o contido"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Produciuse un erro ao gardar a gravación da pantalla"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Volver"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Inicio"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autenticouse a cara"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar o proceso"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Usouse o desbloqueo facial."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplía parte da pantalla"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir configuración da ampliación"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Pechar configuración de ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastrar a esquina para cambiar o tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desprazamento diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Estase reproducindo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> estase executando"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pór en pausa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Asistente está escoitando"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Toma de notas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta o lapis óptico a un cargador"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"O lapis óptico ten pouca batería"</string>
<string name="video_camera" msgid="7654002575156149298">"Videocámara"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Non se pode chamar desde aplicacións persoais"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"A túa organización só che permite chamar desde aplicacións do traballo"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar ao perfil de traballo"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar unha aplicación para teléfonos do traballo"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Para personalizar a pantalla de bloqueo, primeiro desbloquea o dispositivo"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi non dispoñible"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 7a73d8613612..d3b20b303014 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"શેર કરો"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"જોવા માટે ટૅપ કરો"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"સ્ક્રીન રેકોર્ડિંગ સાચવવામાં ભૂલ આવી"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"પાછળ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"હોમ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ચહેરાનું પ્રમાણીકરણ થયું"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ચહેરા દ્વારા અનલૉક કર્યું."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"પૂર્ણ સ્ક્રીનને મોટી કરો"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"મોટા કરવાના સેટિંગ ખોલો"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"મોટા કરવાના સેટિંગ બંધ કરો"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"કદ બદલવા માટે ખૂણો ખેંચો"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ડાયગોનલ સ્ક્રોલિંગને મંજૂરી આપો"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"કદ બદલો"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>માંથી <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ચાલી રહી છે"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ચલાવો"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"થોભાવો"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"પહેલાનો ટ્રૅક"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant સાંભળી રહ્યું છે"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"નોંધ લેવી"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"બ્રૉડકાસ્ટ કરી રહ્યાં છે"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> બ્રોડકાસ્ટ કરવાનું રોકીએ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"તમારા સ્ટાઇલસને ચાર્જર સાથે કનેક્ટ કરો"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"સ્ટાઇલસની બૅટરીમાં ચાર્જ ઓછો છે"</string>
<string name="video_camera" msgid="7654002575156149298">"વીડિયો કૅમેરા"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"કોઈ વ્યક્તિગત ઍપ પરથી કૉલ કરી શકાશે નહીં"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી કૉલ કરવાની મંજૂરી આપે છે"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ઑફિસ માટેની કોઈ ફોન ઍપ ઇન્સ્ટૉલ કરો"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"રદ કરો"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"લૉક સ્ક્રીન કસ્ટમાઇઝ કરો"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"લૉક સ્ક્રીનને કસ્ટમાઇઝ કરવા માટે અનલૉક કરો"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index dd4a7684c4d2..354ada8ad821 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -111,12 +111,12 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"शुरू करें"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रीन को रिकॉर्ड किया जा रहा है"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रीन और ऑडियो, दोनों रिकॉर्ड हो रहे हैं"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां छुआ गया, ये दिखाएं"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां-कहां छुआ गया, यह दिखाएं"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"रोकें"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रिकॉर्डिंग सेव की गई"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"देखने के लिए टैप करें"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रिकॉर्डिंग सेव करते समय गड़बड़ी हुई"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
<string name="accessibility_back" msgid="6530104400086152611">"वापस जाएं"</string>
<string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरे की पुष्टि हो गई"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहरे से अनलॉक किया. जारी रखने के लिए, अनलॉक आइकॉन को दबाएं."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"चेहरे से अनलॉक किया गया."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
@@ -289,7 +289,7 @@
<string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> उपयोग किया गया"</string>
<string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"<xliff:g id="DATA_LIMIT">%s</xliff:g> सीमा"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावनी"</string>
- <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन"</string>
+ <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"वर्क ऐप्लिकेशन"</string>
<string name="quick_settings_night_display_label" msgid="8180030659141778180">"नाइट लाइट"</string>
<string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"शाम को चालू की जाएगी"</string>
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"सुबह तक चालू रहेगी"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फ़ुल स्क्रीन को ज़ूम करें"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीन के किसी हिस्से को ज़ूम करें"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ज़ूम करने की सुविधा वाली सेटिंग खोलें"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ज़ूम करने की सुविधा वाली सेटिंग को बंद करें"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"साइज़ बदलने के लिए, कोने को खींचें और छोड़ें"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरछी दिशा में स्क्रोल करने की अनुमति दें"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"साइज़ बदलें"</string>
@@ -911,7 +912,7 @@
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"बदलाव सेव नहीं किए गए"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"दूसरे ऐप्लिकेशन देखें"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"फिर से व्यवस्थित करें"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कंट्रोल बटन जोड़ें"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कंट्रोल जोड़ें"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"बदलाव करने के लिए वापस जाएं"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"कंट्रोल लोड नहीं किए जा सके. <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन देखें, ताकि यह पक्का किया जा सके कि ऐप्लिकेशन की सेटिंग में कोई बदलाव नहीं हुआ है."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"इस सेटिंग के साथ काम करने वाले कंट्रोल उपलब्ध नहीं हैं"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चल रहा है"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> में से <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> चालू है"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"चलाएं"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"रोकें"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"पिछला ट्रैक"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant सुन रही है"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}one{# सूचना}other{# सूचनाएं}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"नोट बनाएं"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 5b0e411b831c..a66e21bd34e4 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Snimanje zaslona spremljeno"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite za prikaz"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pogreška prilikom brisanja snimanja zaslona"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Pogreška prilikom spremanja snimke zaslona"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Natrag"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je autentificirano"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi za dovršetak"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste nastavili."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Otključano licem."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
@@ -210,7 +210,7 @@
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
<string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brze postavke i zaslon obavijesti."</string>
<string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključavanje zaslona."</string>
- <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan zaslon radnog profila"</string>
+ <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključani zaslon radnog profila"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvaranje"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
@@ -758,7 +758,7 @@
<string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uređivanje redoslijeda postavki."</string>
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Izbornik tipke za uključivanje/isključivanje"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
- <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan zaslon"</string>
+ <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani zaslon"</string>
<string name="thermal_shutdown_title" msgid="2702966892682930264">"Telefon se isključio zbog vrućine"</string>
<string name="thermal_shutdown_message" msgid="6142269839066172984">"Telefon sad radi normalno.\nDodirnite za više informacija"</string>
<string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"Telefon se pregrijao, stoga se isključio kako bi se ohladio Telefon sada radi normalno.\n\nTelefon se može pregrijati ako:\n • upotrebljavate zahtjevne aplikacije (kao što su igre, aplikacije za videozapise ili navigaciju)\n • preuzimate ili prenosite velike datoteke\n • upotrebljavate telefon na visokim temperaturama."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povećajte cijeli zaslon"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povećaj dio zaslona"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori postavke povećavanja"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zatvori postavke povećavanja"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Povucite kut da biste promijenili veličinu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dopusti dijagonalno pomicanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promijeni veličinu"</string>
@@ -922,7 +923,7 @@
<string name="controls_dialog_message" msgid="342066938390663844">"Preporuka s kanala <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Prikazati uređaje i omogućiti upravljanje njima na zaključanom zaslonu?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključan zaslon možete dodati kontrole za svoje vanjske uređaje.\n\nAplikacija vašeg uređaja može vam dopustiti upravljanje nekim uređajima bez otključavanja telefona ili tableta.\n\nPromjene uvijek možete unijeti u Postavkama."</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključani zaslon možete dodati kontrole za svoje vanjske uređaje.\n\nAplikacija vašeg uređaja može vam dopustiti upravljanje nekim uređajima bez otključavanja telefona ili tableta.\n\nPromjene uvijek možete unijeti u Postavkama."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Upravljati uređajima na zaključanom zaslonu?"</string>
<string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Nekim uređajima možete upravljati bez otključavanja telefona ili tableta. Aplikacija vašeg uređaja odlučuje kojim se uređajima može upravljati na taj način."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> reproducira se putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproduciraj"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodni zapis"</string>
@@ -1055,7 +1057,7 @@
<string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
<string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
<string name="mobile_data_poor_connection" msgid="819617772268371434">"Slaba veza"</string>
- <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilna veza neće se automatski uspostaviti"</string>
+ <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilni podaci neće se automatski prenositi"</string>
<string name="mobile_data_no_connection" msgid="1713872434869947377">"Niste povezani"</string>
<string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nije dostupna nijedna druga mreža"</string>
<string name="all_network_unavailable" msgid="4112774339909373349">"Nema dostupnih mreža"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent sluša"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pisanje bilježaka"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
@@ -1148,7 +1153,7 @@
<string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instaliraj poslovnu aplikaciju telefona"</string>
<string name="call_from_work_profile_close" msgid="5830072964434474143">"Odustani"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje zaslona"</string>
- <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključan zaslon"</string>
+ <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključani zaslon"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nije dostupan"</string>
<string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
<string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Blokirani su kamera i mikrofon"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 8fb8537c723e..7284bb3cdd07 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Megosztás"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Képernyőfelvétel elmentve"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Koppintson a megtekintéshez"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Hiba történt a képernyőrögzítés mentése során"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Vissza"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Főoldal"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Arc hitelesítve"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Megerősítve"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Koppintson a Megerősítés lehetőségre"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Arccal feloldva. A folytatáshoz nyomja meg a feloldás ikont."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Zárolás arccal feloldva."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"A teljes képernyő felnagyítása"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Képernyő bizonyos részének nagyítása"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Nagyítási beállítások megnyitása"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Nagyítási beállítások bezárása"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Az átméretezéshez húzza a kívánt sarkot"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Átlós görgetés engedélyezése"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Átméretezés"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című száma hallható itt: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg fut"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Lejátszás"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Szünet"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Előző szám"</string>
@@ -1065,7 +1067,7 @@
<string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Hálózatok keresése…"</string>
<string name="wifi_failed_connect_message" msgid="4161863112079000071">"Nem sikerült hálózathoz csatlakozni."</string>
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"A Wi-Fi-re történő csatlakozás jelenleg nem automatikus"</string>
- <string name="see_all_networks" msgid="3773666844913168122">"Megtekintés"</string>
+ <string name="see_all_networks" msgid="3773666844913168122">"Összes megtekintése"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Hálózatváltáshoz válassza le az ethernetet"</string>
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"Az eszközhasználati élmény javítása érdekében az alkalmazások és a szolgáltatások továbbra is bármikor kereshetnek Wi-Fi-hálózatokat, még akkor is, ha a Wi-Fi ki van kapcsolva. A funkciót a Wi-Fi-keresési beállításoknál módosíthatja. "<annotation id="link">"Módosítás"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Repülős üzemmód kikapcsolása"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"A Segéd figyel"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Jegyzetelés"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 801efc441cba..c419a3c8bd9b 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Կիսվել"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Էկրանի տեսագրությունը պահվեց"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Հպեք՝ դիտելու համար"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Չհաջողվեց ջնջել տեսագրությունը"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Չհաջողվեց պահել էկրանի տեսագրությունը"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Հետ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Տուն"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Դեմքը ճանաչվեց"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Հաստատվեց"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ավարտելու համար հպեք «Հաստատել»"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ապակողպվել է դեմքով։ Սեղմեք ապակողպման պատկերակը։"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Ապակողպվել է դեմքով։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Խոշորացնել ամբողջ էկրանը"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Խոշորացնել էկրանի որոշակի հատվածը"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Բացել խոշորացման կարգավորումները"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Փակել խոշորացման կարգավորումները"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Քաշեք անկյունը՝ չափը փոխելու համար"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Թույլատրել անկյունագծով ոլորումը"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Փոխել չափը"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Այժմ նվագարկվում է <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>՝ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ից"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն աշխատում է"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Նվագարկել"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Դադարեցնել"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Նախորդ կատարումը"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Օգնականը լսում է"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ծանուցում}one{# ծանուցում}other{# ծանուցում}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Նշումների ստեղծում"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6a95903dc32c..44a9a2a4212e 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bagikan"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Perekaman layar disimpan"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ketuk untuk melihat"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error saat menghapus rekaman layar"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Terjadi error saat menyimpan rekaman layar"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Utama"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah diautentikasi"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Dikonfirmasi"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketuk Konfirmasi untuk menyelesaikan"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk melanjutkan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Kunci dibuka dengan wajah."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Memperbesar tampilan layar penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Perbesar sebagian layar"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Buka setelan pembesaran"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Tutup setelan pembesaran"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Tarik pojok persegi untuk mengubah ukuran"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Izinkan scrolling diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ubah ukuran"</string>
@@ -910,7 +911,7 @@
<string name="controls_favorite_removed" msgid="5276978408529217272">"Semua kontrol dihapus"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Perubahan tidak disimpan"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Lihat aplikasi lainnya"</string>
- <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Atur ulang"</string>
+ <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Tata ulang"</string>
<string name="controls_favorite_add_controls" msgid="1221420435546694004">"Tambahkan kontrol"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Kembali mengedit"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrol tidak dapat dimuat. Periksa aplikasi <xliff:g id="APP">%s</xliff:g> untuk memastikan setelan aplikasi tidak berubah."</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sedang diputar dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> dari <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Putar"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Jeda"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Lagu sebelumnya"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant sedang mendengarkan"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pembuatan catatan"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 31d9b415483b..fbcbbe1694bc 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deila"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Skjáupptaka vistuð"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ýttu til að skoða"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Villa við að eyða skjáupptöku"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Villa við að vista skjáupptöku"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Til baka"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Heim"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Andlit staðfest"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Staðfest"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ýttu á „Staðfesta“ til að ljúka"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Opnað með andliti. Ýttu á táknið taka úr lás til að halda áfram."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Opnað með andliti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Stækka allan skjáinn"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Stækka hluta skjásins"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Opna stillingar stækkunar"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Loka stillingum stækkunar"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dragðu horn til að breyta stærð"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Leyfa skáflettingu"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Breyta stærð"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> er í spilun á <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> er í gangi"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Spila"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Gera hlé"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Fyrra lag"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Hjálparinn er að hlusta"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Glósugerð"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6e6bef90917d..8fe832660ae9 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Registrazione schermo salvata"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore durante il salvataggio della registrazione dello schermo"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Indietro"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Volto autenticato"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confermato"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tocca Conferma per completare"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Sbloccato con il volto. Premi l\'icona Sblocca e continua."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Sbloccato con il volto."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
@@ -306,7 +306,7 @@
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string>
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string>
- <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Registrazione dello schermo"</string>
+ <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Registrazione schermo"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inizia"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Interrompi"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modalità a una mano"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ingrandisci l\'intero schermo"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ingrandisci parte dello schermo"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Apri le impostazioni di ingrandimento"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Chiudi impostazioni di ingrandimento"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Trascina l\'angolo per ridimensionare"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Scorrimento diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ridimensiona"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> è in riproduzione da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> di <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Riproduci"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Metti in pausa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Traccia precedente"</string>
@@ -972,7 +974,7 @@
<string name="controls_menu_add" msgid="4447246119229920050">"Aggiungi controlli"</string>
<string name="controls_menu_edit" msgid="890623986951347062">"Modifica controlli"</string>
<string name="controls_menu_add_another_app" msgid="8661172304650786705">"Aggiungi app"</string>
- <string name="controls_menu_remove" msgid="3006525275966023468">"Rimuovi l\'app"</string>
+ <string name="controls_menu_remove" msgid="3006525275966023468">"Rimuovi app"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"Aggiungi uscite"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppo"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selezionato"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'assistente è in ascolto"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}many{# notifiche}other{# notifiche}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Aggiunta di note"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connetti lo stilo a un caricabatterie"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Batteria stilo in esaurimento"</string>
<string name="video_camera" msgid="7654002575156149298">"Videocamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossibile fare chiamate da un\'app personale"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"La tua organizzazione consente di fare chiamate solo dalle app di lavoro"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Passa al profilo di lavoro"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installa un\'app di lavoro per smartphone"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annulla"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Personalizza schermata di blocco"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Sblocca per personalizzare la schermata di blocco"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non disponibile"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index ad26a40bb3b3..fb8724951659 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -100,7 +100,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"להתחיל את ההקלטה?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מנוגן במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"‏בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"התחלת ההקלטה"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"הקלטת אודיו"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"הקלטת המסך נשמרה"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"שגיאה במחיקת הקלטת המסך"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"שגיאה בשמירה של הקלטת המסך"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
<string name="accessibility_back" msgid="6530104400086152611">"חזרה"</string>
<string name="accessibility_home" msgid="5430449841237966217">"בית"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"הנעילה בוטלה בזיהוי פנים. להמשך, לוחצים על סמל ביטול הנעילה."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"הנעילה בוטלה באמצעות זיהוי הפנים."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"הגדלה של המסך המלא"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"הגדלת חלק מהמסך"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"פתיחת הגדרות ההגדלה"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"סגירת הגדרות ההגדלה"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"צריך לגרור את הפינה כדי לשנות את הגודל"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"הפעלת גלילה באלכסון"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"שינוי גודל"</string>
@@ -906,7 +907,7 @@
<string name="accessibility_control_move" msgid="8980344493796647792">"העברה למיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"פקדים"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"יש לבחור פקדי מכשירים כדי לקבל גישה מהירה"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"יש ללחוץ לחיצה ארוכה ולגרור כדי לארגן מחדש את הפקדים"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"כדי לארגן מחדש את הפקדים, צריך ללחוץ לחיצה ארוכה ולגרור"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"כל הפקדים הוסרו"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"השינויים לא נשמרו"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"הצגת אפליקציות אחרות"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מופעל מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> מתוך <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"הפעלה"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"השהיה"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"הטראק הקודם"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‏Assistant מאזינה"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}one{# התראות}two{# התראות}other{# התראות}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"כתיבת הערות"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 040f6b040279..bd12f1eaab27 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -100,8 +100,8 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"録画を開始しますか?"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"録画中は、画面に表示される内容やデバイスで再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"アプリの録画中は、そのアプリで表示または再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"録画中は、表示や再生される内容に Android がアクセスできます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"アプリの録画中は、そのアプリで表示または再生される内容に Android がアクセスできます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"録画を開始"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"録音"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"デバイスの音声"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"共有"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"画面の録画を保存しました"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"タップすると表示されます"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"画面の録画の削除中にエラーが発生しました"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"画面の録画の保存中にエラーが発生しました"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
<string name="accessibility_back" msgid="6530104400086152611">"戻る"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ホーム"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"顔を認証しました"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"顔でロック解除しました。アイコンを押すと続行します。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"顔でロック解除しました。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
@@ -394,9 +394,9 @@
<string name="user_remove_user_message" msgid="6702834122128031833">"このユーザーのアプリとデータがすべて削除されます。"</string>
<string name="user_remove_user_remove" msgid="8387386066949061256">"削除"</string>
<string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> で録画やキャストを開始しますか?"</string>
- <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中またはキャスト中に画面に表示される情報や、デバイスで再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+ <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中またはキャスト中に画面上に表示または再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、音声などが含まれます。"</string>
<string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"録画やキャストを開始しますか?"</string>
- <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"この機能を提供するサービスは、録画中またはキャスト中に画面上に表示される情報や、デバイスで再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+ <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"この機能を提供するサービスは、録画中またはキャスト中に画面上に表示または再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、音声などが含まれます。"</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"画面全体"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"1 つのアプリ"</string>
<string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"アプリの共有または録画"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"画面全体を拡大します"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"画面の一部を拡大します"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"画面の拡大設定を開く"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"拡大の設定を閉じる"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"サイズを変更するには角をドラッグ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"斜めスクロールを許可"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"サイズ変更"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)が <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生中"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> を実行しています"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"再生"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"一時停止"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"前のトラック"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"アシスタントが音声認識中です"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>、<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"メモ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ブロードキャスト"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> のブロードキャストを停止しますか?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index a7acb78ecd84..a2f1fb675470 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"გაზიარება"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ეკრანის ჩაწერა შეინახა"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"შეეხეთ სანახავად"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ეკრანის ჩანაწერის შენახვისას შეცდომა მოხდა"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
<string name="accessibility_back" msgid="6530104400086152611">"უკან"</string>
<string name="accessibility_home" msgid="5430449841237966217">"საწყისი"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"სახის ამოცნობილია"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"დადასტურებული"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"განიბლოკა სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"განიბლოკა სახით."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"გაადიდეთ სრულ ეკრანზე"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ეკრანის ნაწილის გადიდება"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"გახსენით გადიდების პარამეტრები"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"გადიდების პარამეტრების დახურვა"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ჩავლებით გადაიტანეთ კუთხე ზომის შესაცვლელად"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"დიაგონალური გადაადგილების დაშვება"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ზომის შეცვლა"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, უკრავს <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-დან <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაშვებულია"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"დაკვრა"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"პაუზა"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"წინა ჩანაწერი"</string>
@@ -1106,7 +1108,8 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ასისტენტი უსმენს"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"შენიშვნების ჩაწერა"</string>
+ <string name="note_task_button_label" msgid="230135078402003532">"ჩანიშვნა"</string>
+ <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ჩანიშვნა, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string>
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"იწყებთ მაუწყებლობას"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string>
@@ -1142,15 +1145,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"დააკავშირეთ თქვენი სტილუსი დამტენს"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"სტილუსის ბატარეა დაცლის პირასაა"</string>
<string name="video_camera" msgid="7654002575156149298">"ვიდეოკამერა"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"პირადი აპიდან დარეკვა შეუძლებელია"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"თქვენი ორგანიზაცია ნებას გრთავთ, რომ დარეკოთ მხოლოდ სამსახურის აპებიდან"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"სამსახურის ტელეფონის აპის ინსტალაცია"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"გაუქმება"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"ჩაკეთილი ეკრანის მორგება"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ჩაკეტილი ეკრანის მოსარგებად გაბლოკეთ"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi მიუწვდომელია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 23174547c4df..709ac782634c 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Экран жазбасы сақталды."</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран жазбасын сақтау кезінде қате шықты."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
<string name="accessibility_back" msgid="6530104400086152611">"Артқа"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Үй"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Бет танылды."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Бет үлгісі арқылы ашылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Бетпен ашылды."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толық экранды ұлғайту"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экранның бөлігін ұлғайту"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ұлғайту параметрлерін ашу"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Ұлғайту параметрлерін жабу"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Өлшемін өзгерту үшін бұрышынан сүйреңіз."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ бойынша айналдыруға рұқсат беру"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлшемін өзгерту"</string>
@@ -907,7 +908,7 @@
<string name="controls_favorite_default_title" msgid="967742178688938137">"Басқару элементтері"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"Жылдам кіру үшін құрылғыны басқару элементтерін таңдаңыз."</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Басқару элементтерінің ретін өзгерту үшін оларды басып тұрып сүйреңіз."</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"Барлық басқару элементтері жойылды."</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"Барлық басқару элементі жойылды."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Өзгерістер сақталмады."</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Басқа қолданбаларды көру"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Қайта реттеу"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әні ойнатылуда."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> қосулы тұр"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Ойнату"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Кідірту"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Алдыңғы трек"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant тыңдап тұр."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}other{# хабарландыру}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Ескертпе жазу"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусты зарядтағышқа жалғаңыз."</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Стилус батареясының заряды аз"</string>
<string name="video_camera" msgid="7654002575156149298">"Бейнекамера"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Жеке қолданбадан қоңырау шалу мүмкін емес"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ұйымыңыз тек жұмыс қолданбаларынан қоңырау шалуға рұқсат етеді."</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Жұмысқа арналған телефон қолданбасын орнату"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Бас тарту"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Құлып экранын бейімдеу"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Құлып экранын бейімдеу үшін құлыпты ашыңыз"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi қолжетімсіз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index ed82b8d33fd5..9fb141bd28f0 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"ចែករំលែក"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"បានរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ចុចដើម្បីមើល"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"មានបញ្ហា​ក្នុងការ​លុបការថត​សកម្មភាព​អេក្រង់"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"មានបញ្ហាក្នុងការរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហា​ក្នុងការ​ចាប់ផ្ដើម​ថត​អេក្រង់"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ថយក្រោយ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"គេហ​ទំព័រ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"បានដោះសោដោយប្រើមុខ។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
@@ -169,14 +169,14 @@
<string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"កុំទាន់"</string>
<string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"តម្រូវឱ្យ​កែលម្អ​សុវត្ថិភាព និងប្រតិបត្តិការ"</string>
<string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"រៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត"</string>
- <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ការដោះសោ​ដោយប្រើ​ស្នាមម្រាមដៃ"</string>
+ <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃ"</string>
<string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"រៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃ"</string>
<string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"ដើម្បីរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត គំរូ និងរូបភាពស្នាមម្រាមដៃបច្ចុប្បន្នរបស់អ្នកនឹងត្រូវបានលុប។\n\nបន្ទាប់ពីលុបគំរូនិងរូបភាពស្នាមម្រាមដៃទាំងនោះ អ្នកនឹងត្រូវរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នក ឬផ្ទៀងផ្ទាត់ថាជាអ្នក។"</string>
<string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"ដើម្បីរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត គំរូ និងរូបភាពស្នាមម្រាមដៃបច្ចុប្បន្នរបស់អ្នកនឹងត្រូវបានលុប។\n\nបន្ទាប់ពីលុបគំរូនិងរូបភាពស្នាមម្រាមដៃទាំងនោះ អ្នកនឹងត្រូវរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នក ឬផ្ទៀងផ្ទាត់ថាជាអ្នក។"</string>
<string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"មិនអាចរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃបានទេ។ សូមចូលទៅកាន់​ការកំណត់​ ដើម្បីព្យាយាមម្ដងទៀត។"</string>
<string name="face_re_enroll_notification_title" msgid="1850838867718410520">"រៀបចំ​ការដោះសោតាមទម្រង់មុខ​ម្ដងទៀត"</string>
- <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ដោះ​សោ​តាម​​ទម្រង់​មុខ"</string>
- <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"រៀបចំ​ការដោះសោ​តាមទម្រង់មុខ"</string>
+ <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ការដោះ​សោ​ដោយស្កេន​មុខ"</string>
+ <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"រៀបចំ​ការដោះសោ​ដោយស្កេនមុខ"</string>
<string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"ដើម្បីរៀបចំ​ដោះសោតាមទម្រង់មុខ​ម្ដងទៀត គំរូមុខបច្ចុប្បន្ន​របស់អ្នក​នឹងត្រូវបានលុប។\n\nអ្នកនឹងត្រូវ​រៀបចំមុខងារនេះ​ម្ដងទៀត ដើម្បីប្រើមុខរបស់អ្នក​សម្រាប់ដោះសោទូរសព្ទរបស់អ្នក។"</string>
<string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"មិនអាច​រៀបចំ​ការដោះសោតាមទម្រង់មុខបានទេ។ សូមចូលទៅកាន់​ការកំណត់​ ដើម្បីព្យាយាមម្ដងទៀត។"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ប៉ះ​ឧបករណ៍​ចាប់ស្នាម​ម្រាមដៃ"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ពង្រីក​ពេញអេក្រង់"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ពង្រីក​ផ្នែកនៃ​អេក្រង់"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"បើកការកំណត់​ការពង្រីក"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"បិទការកំណត់ការពង្រីក"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"អូសជ្រុងដើម្បីប្ដូរទំហំ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"អនុញ្ញាត​ការរំកិលបញ្ឆិត"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ប្ដូរ​ទំហំ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> កំពុងចាក់ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> នៃ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ចាក់"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ផ្អាក"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ចម្រៀងមុន"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google Assistant កំពុងស្តាប់"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"ការកត់ត្រា​"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នក​ផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹង​បញ្ឈប់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 4ca1495ffc89..749173991f42 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -98,7 +98,7 @@
<string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
<string name="screenrecord_title" msgid="4257171601439507792">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
- <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
+ <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
<string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸಬೇಕೇ?"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ನೀವು ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಉಳಿಸಲಾಗಿದೆ"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೇವ್‌ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ಹಿಂದೆ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ಮುಖಪುಟ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
@@ -214,7 +214,7 @@
<string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚು"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
- <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ಅಡಚಣೆ ಮಾಡಬೇಡ."</string>
+ <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ಬ್ಲೂಟೂತ್."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ."</string>
<string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> ಗಂಟೆಗೆ ಅಲಾರಮ್ ಹೊಂದಿಸಲಾಗಿದೆ."</string>
@@ -236,7 +236,7 @@
<string name="dessert_case" msgid="9104973640704357717">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
<string name="start_dreams" msgid="9131802557946276718">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
<string name="ethernet_label" msgid="2203544727007463351">"ಇಥರ್ನೆಟ್"</string>
- <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
+ <string name="quick_settings_dnd_label" msgid="7728690179108024338">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ಬ್ಲೂಟೂತ್‌"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ಯಾವುದೇ ಜೋಡಿಸಲಾದ ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string>
@@ -504,7 +504,7 @@
<string name="stream_ring" msgid="7550670036738697526">"ರಿಂಗ್"</string>
<string name="stream_music" msgid="2188224742361847580">"ಮಾಧ್ಯಮ"</string>
<string name="stream_alarm" msgid="16058075093011694">"ಅಲಾರಮ್"</string>
- <string name="stream_notification" msgid="7930294049046243939">"ಅಧಿಸೂಚನೆ"</string>
+ <string name="stream_notification" msgid="7930294049046243939">"ನೋಟಿಫಿಕೇಶನ್"</string>
<string name="stream_bluetooth_sco" msgid="6234562365528664331">"ಬ್ಲೂಟೂತ್‌"</string>
<string name="stream_dtmf" msgid="7322536356554673067">"ಡ್ಯುಯಲ್‌ ಬಹು ಟೋನ್ ಆವರ್ತನೆ"</string>
<string name="stream_accessibility" msgid="3873610336741987152">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
@@ -556,9 +556,9 @@
<string name="enable_bluetooth_title" msgid="866883307336662596">"ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕೆ?"</string>
<string name="enable_bluetooth_message" msgid="6740938333772779717">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಅನ್ನು ಟ್ಯಾಬ್ಲೆಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು, ನೀವು ಮೊದಲು ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string>
<string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"ಆನ್‌ ಮಾಡಿ"</string>
- <string name="tuner_full_importance_settings" msgid="1388025816553459059">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="tuner_full_importance_settings" msgid="1388025816553459059">"ಪವರ್ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳು"</string>
<string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ಆನ್ ಆಗಿದೆ - ಮುಖ-ಆಧಾರಿತ"</string>
- <string name="power_notification_controls_description" msgid="1334963837572708952">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಅಧಿಸೂಚನೆಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
+ <string name="power_notification_controls_description" msgid="1334963837572708952">"ಪವರ್ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಆ್ಯಪ್‍ಗಳ ನೋಟಿಫಿಕೇಶನ್‍ಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ನೋಟಿಫಿಕೇಶನ್ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ನೋಟಿಫಿಕೇಶನ್ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಆ್ಯಪ್‍ನಿಂದ ಎಲ್ಲಾ ನೋಟಿಫಿಕೇಶನ್‍ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
<string name="inline_done_button" msgid="6043094985588909584">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="inline_ok_button" msgid="603075490581280343">"ಅನ್ವಯಿಸಿ"</string>
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
@@ -591,15 +591,15 @@
<string name="feedback_promoted" msgid="2125562787759780807">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್‌ನಲ್ಲಿ &lt;b&gt;ಉನ್ನತ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ&lt;/b&gt;."</string>
<string name="feedback_demoted" msgid="951884763467110604">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್‌ನಲ್ಲಿ &lt;b&gt;ಕಡಿಮೆ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ&lt;/b&gt;."</string>
<string name="feedback_prompt" msgid="3656728972307896379">"ನಿಮ್ಮ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಡೆವಲಪರ್‌ಗೆ ತಿಳಿಸಿ. ಇದು ಸರಿಯಾಗಿತ್ತೇ?"</string>
- <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆರೆಯಲಾಗಿದೆ"</string>
- <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
+ <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆರೆಯಲಾಗಿದೆ"</string>
+ <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="notification_more_settings" msgid="4936228656989201793">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="notification_app_settings" msgid="8963648463858039377">"ಕಸ್ಟಮೈಜ್‌ ಮಾಡಿ"</string>
<string name="notification_conversation_bubble" msgid="2242180995373949022">"ಬಬಲ್ ತೋರಿಸಿ"</string>
<string name="notification_conversation_unbubble" msgid="6908427185031099868">"ಬಬಲ್ಸ್‌ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="notification_menu_gear_description" msgid="6429668976593634862">"ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
- <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ಅಧಿಸೂಚನೆ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
+ <string name="notification_menu_gear_description" msgid="6429668976593634862">"ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ನೋಟಿಫಿಕೇಶನ್ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
<string name="notification_menu_snooze_action" msgid="5415729610393475019">"ನನಗೆ ಜ್ಞಾಪಿಸಿ"</string>
<string name="snooze_undo" msgid="2738844148845992103">"ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
@@ -682,7 +682,7 @@
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
<string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ಕ್ಯಾಲ್ಕ್ಯುಲೇಟರ್"</string>
<string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
- <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
+ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌"</string>
<string name="battery" msgid="769686279459897127">"ಬ್ಯಾಟರಿ"</string>
<string name="headset" msgid="4485892374984466437">"ಹೆಡ್‌ಸೆಟ್"</string>
@@ -747,7 +747,7 @@
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ಟೈಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ಟೈಲ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳ ಎಡಿಟರ್."</string>
- <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+ <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ನೋಟಿಫಿಕೇಶನ್: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
<string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
<string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮುಚ್ಚಿ."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ಹಿಗ್ಗಿಸಿ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ಸ್ಕ್ರೀನ್‌ನ ಅರ್ಧಭಾಗವನ್ನು ಝೂಮ್ ಮಾಡಿ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ಹಿಗ್ಗಿಸುವಿಕೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ಮ್ಯಾಗ್ನಿಫಿಕೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮುಚ್ಚಿರಿ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ಮರುಗಾತ್ರಗೊಳಿಸಲು ಮೂಲೆಯನ್ನು ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ಡಯಾಗನಲ್ ಸ್ಕ್ರೋಲಿಂಗ್ ಅನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
@@ -911,7 +912,7 @@
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಲಾಗಿಲ್ಲ"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"ಇತರ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"ಮರುಹೊಂದಿಸಿ"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"ಕಂಟ್ರೋಲ್‌ಗಳನ್ನು ಸೇರಿಸಿ"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"ಎಡಿಟ್ ಮಾಡುವಿಕೆಗೆ ಹಿಂತಿರುಗಿ"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"ನಿಯಂತ್ರಣಗಳನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಆ್ಯಪ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಬದಲಾಗಿಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"ಹೊಂದಾಣಿಕೆಯ ನಿಯಂತ್ರಣಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ಪ್ಲೇ ಮಾಡಿ"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ವಿರಾಮಗೊಳಿಸಿ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ಹಿಂದಿನ ಟ್ರ್ಯಾಕ್"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ಅಸಿಸ್ಟೆಂಟ್ ಆಲಿಸುತ್ತಿದೆ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ನೋಟಿಫಿಕೇಶನ್}one{# ನೋಟಿಫಿಕೇಶನ್‌ಗಳು}other{# ನೋಟಿಫಿಕೇಶನ್‌ಗಳು}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"ಟಿಪ್ಪಣಿಗಳನ್ನು ಬರೆದುಕೊಳ್ಳುವುದು"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ನಿಮ್ಮ ಸ್ಟೈಲಸ್ ಅನ್ನು ಚಾರ್ಜರ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"ಸ್ಟೈಲಸ್ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಿದೆ"</string>
<string name="video_camera" msgid="7654002575156149298">"ವೀಡಿಯೊ ಕ್ಯಾಮರಾ"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ನಿಂದ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ಕೆಲಸದ ಫೋನ್ ಆ್ಯಪ್ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e3c2a65445bc..e2fc448ff7ce 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"공유"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"화면 녹화 저장됨"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"탭하여 보기"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"화면 녹화 저장 중에 오류가 발생했습니다."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
<string name="accessibility_back" msgid="6530104400086152611">"뒤로"</string>
<string name="accessibility_home" msgid="5430449841237966217">"홈"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"얼굴이 인증되었습니다."</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 잠금 해제 아이콘을 누르세요."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"얼굴 인식으로 잠금 해제되었습니다."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"전체 화면 확대"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"화면 일부 확대"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"확대 설정 열기"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"확대 설정 닫기"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"모서리를 드래그하여 크기 조절"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"대각선 스크롤 허용"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"크기 조절"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생 중"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> 실행 중"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"재생"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"일시중지"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"이전 트랙"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"어시스턴트가 대기 중입니다."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}other{알림 #개}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"메모"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 604aaadff4ef..ef84cb5d4631 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлүшүү"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Экрандан жаздырылган нерсе сакталды"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Көрүү үчүн таптаңыз"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран тартылган жок"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Артка"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Үйгө"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Жүздүн аныктыгы текшерилди"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ырасталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Түзмөгүңүздү жүзүңүз менен ачтыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толук экранда ачуу"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экрандын бир бөлүгүн чоңойтуу"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Чоңойтуу параметрлерин ачуу"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Чоңойтуу параметрлерин жабуу"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Өлчөмүн өзгөртүү үчүн бурчун сүйрөңүз"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ боюнча сыдырууга уруксат берүү"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлчөмүн өзгөртүү"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ичинен <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> иштеп жатат"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Ойнотуу"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Тындыруу"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Мурунку трек"</string>
@@ -993,7 +995,7 @@
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string>
<string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string>
<string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string>
- <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Кабарыңызды угуу үчүн жакын жердеги кишилер шайкеш Bluetooth түзмөктөрү менен QR кодун скандап же кабарлоонун аталышын жана сырсөзүн колдоно алышат"</string>
+ <string name="media_output_broadcasting_message" msgid="4150299923404886073">"Кабарыңызды угуу үчүн жакын жердеги кишилер шайкеш Bluetooth түзмөктөрү менен QR кодду скандап же кабарлоонун аталышын жана сырсөзүн колдоно алышат"</string>
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Кабарлоонун аталышы"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Сырсөз"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сактоо"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Жардамчы угуп жатат"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Эскертме жазуу"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 05364072d81c..3ca429fce20d 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"ແບ່ງປັນ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ຈັດເກັບການບັນທຶກໜ້າຈໍແລ້ວ"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ແຕະເພື່ອເບິ່ງ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ກັບຄືນ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ໜ້າທຳອິດ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ຢືນຢັນແລ້ວ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ຂະຫຍາຍເຕັມຈໍ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ເປີດການຕັ້ງຄ່າການຂະຫຍາຍ"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ປິດການຕັ້ງຄ່າການຂະຫຍາຍ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ລາກຢູ່ມຸມເພື່ອປັບຂະໜາດ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ອະນຸຍາດໃຫ້ເລື່ອນທາງຂວາງ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ປ່ຽນຂະໜາດ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ກຳລັງຫຼິ້ນຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ຈາກ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງເຮັດວຽກຢູ່"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ຫຼິ້ນ"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ຢຸດຊົ່ວຄາວ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ເພງກ່ອນໜ້າ"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ຜູ້ຊ່ວຍກຳລັງຟັງ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}other{# ການແຈ້ງເຕືອນ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"ການຈົດບັນທຶກ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index de4517e73e5e..84b405b386cb 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Bendrinti"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrano vaizdo įrašas išsaugotas"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Palieskite, kad peržiūrėtumėte"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ištrinant ekrano įrašą įvyko klaida"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Išsaugant ekrano įrašą įvyko klaida"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atgal"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Pagrindinis"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Veidas autentifikuotas"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Patvirtinta"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atrakinta pagal veidą. Pasp. atrak. pikt., kad tęstumėte."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Atrakinta pagal veidą."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Viso ekrano didinimas"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Didinti ekrano dalį"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Atidaryti didinimo nustatymus"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Uždaryti didinimo nustatymus"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Norėdami keisti dydį, vilkite kampą"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Slinkimo įstrižai leidimas"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Pakeisti dydį"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ leidžiama iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> iš <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ vykdoma"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Paleisti"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pristabdyti"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Ankstesnis takelis"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Padėjėjas klausosi"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Užrašų kūrimas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7fcd3412db48..2b9ecc50b2da 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrāna ieraksts ir saglabāts"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Pieskarieties, lai skatītu"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Saglabājot ekrāna ierakstu, radās kļūda."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
<string name="accessibility_back" msgid="6530104400086152611">"Atpakaļ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Sākums"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Seja autentificēta"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Apstiprināts"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atbloķēta ar seju. Turpināt: nospiediet atbloķēšanas ikonu."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Ierīce atbloķēta pēc sejas."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Palielināt visu ekrānu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Palielināt ekrāna daļu"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Atvērt palielinājuma iestatījumus"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Aizvērt palielinājuma iestatījumus"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Velciet stūri, lai mainītu izmērus"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Atļaut ritināšanu pa diagonāli"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Mainīt lielumu"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tiek atskaņots fails “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> no <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> darbojas"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Atskaņot"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Apturēt"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Iepriekšējais ieraksts"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistents klausās"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Piezīmju pierakstīšana"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Pievienojiet skārienekrāna pildspalvu lādētājam"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Zems skārienekrāna pildspalvas akumulatora līmenis"</string>
<string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nevar zvanīt no personīgās lietotnes"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Jūsu organizācija ļauj jums veikt zvanus tikai no darba lietotnēm."</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalēt darba lietotni Tālrunis"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Atcelt"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Pielāgot bloķēšanas ekrānu"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Bloķēšanas ekrāna pielāgošana pēc atbloķēšanas"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nav pieejams"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index cd68cd7b7154..1596f8bcea7e 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Сподели"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Снимката од екранот е зачувана"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Допрете за прегледување"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Грешка при бришењето на снимката од екранот"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при зачувувањето на снимката од екранот"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Почетна страница"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е проверено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отклучено со лик. Притиснете ја иконата за отклучување за да продолжите."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Отклучено со лице."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лик. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
@@ -177,7 +177,7 @@
<string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Поставете „Отклучување со лик“ повторно"</string>
<string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Отклучување со лик"</string>
<string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Поставување „Отклучување со лик“"</string>
- <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Избришете го моменталниот модел на лице за да поставите „Отклучување со лик“ повторно.\n\nЌе треба повторно да ја поставите функцијава за да го користите ликот за да го отклучите телефонот."</string>
+ <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"За да може одново да поставите „Отклучување со лик“, вашиот сегашен модел на лик ќе се избрише.\n\nЗа да го користите ликот за отклучување на телефонот, ќе треба повторно да ја поставите функцијава."</string>
<string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Не можеше да се постави „Отклучување со лик“. Одете во „Поставки“ за да се обидете повторно."</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Допрете го сензорот за отпечатоци"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Не се препознава ликот. Користете отпечаток."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Зголемете го целиот екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Зголемувајте дел од екранот"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Отвори поставки за зголемување"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Затворете ги поставките за зголемување"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Повлечете на аголот за да ја промените големината"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволете дијагонално лизгање"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Промени големина"</string>
@@ -887,7 +888,7 @@
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"Премести горе десно"</string>
<string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"Премести долу лево"</string>
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Премести долу десно"</string>
- <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Премести до работ и сокриј"</string>
+ <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Премести до работ и скриј"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Премести над работ и прикажи"</string>
<string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Отстрани"</string>
<string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"вклучување/исклучување"</string>
@@ -905,7 +906,7 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"означите како неомилена"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Преместете на позиција <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Контроли"</string>
- <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Изберете контроли на уреди за брз пристап"</string>
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Изберете контроли за уредите до кои ќе имате брз пристап"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржете и влечете за да ги преуредите контролите"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Сите контроли се отстранети"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Промените не се зачувани"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> работи"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Пушти"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Пауза"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песна"</string>
@@ -966,7 +968,7 @@
<string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
<string name="controls_error_removed_message" msgid="2885911717034750542">"Не може да се пристапи до <xliff:g id="DEVICE">%1$s</xliff:g>. Проверете ја апликацијата <xliff:g id="APPLICATION">%2$s</xliff:g> за да се уверите дека контролата е сѐ уште достапна и дека поставките за апликацијата не се сменети."</string>
- <string name="controls_open_app" msgid="483650971094300141">"Отвори апликација"</string>
+ <string name="controls_open_app" msgid="483650971094300141">"Отворете ја апликацијата"</string>
<string name="controls_error_generic" msgid="352500456918362905">"Не може да се вчита статусот"</string>
<string name="controls_error_failed" msgid="960228639198558525">"Грешка, обидете се повторно"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"Додајте контроли"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"„Помошникот“ слуша"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Фаќање белешки"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитување"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 024cf71e0277..09cb9bf247d2 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"പങ്കിടുക"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
<string name="accessibility_back" msgid="6530104400086152611">"മടങ്ങുക"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ഹോം"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"സ്ഥിരീകരിച്ചു"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്തിരിക്കുന്നു."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"സ്ക്രീൻ പൂർണ്ണമായും മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"സ്‌ക്രീനിന്റെ ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"മാഗ്നിഫിക്കേഷൻ ക്രമീകരണം തുറക്കുക"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"മാഗ്നിഫിക്കേഷൻ ക്രമീകരണം അടയ്‌ക്കുക"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"വലുപ്പം മാറ്റാൻ മൂല വലിച്ചിടുക"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ഡയഗണൽ സ്‌ക്രോളിംഗ് അനുവദിക്കുക"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"വലുപ്പം മാറ്റുക"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുന്നു"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ൽ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> റൺ ചെയ്യുന്നു"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"പ്ലേ ചെയ്യുക"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"താൽക്കാലികമായി നിർത്തുക"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"മുമ്പത്തെ ട്രാക്ക്"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant കേൾക്കുന്നു"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"കുറിപ്പ് രേഖപ്പെടുത്തൽ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്‌കാസ്റ്റ് അവസാനിക്കും"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"നിങ്ങളുടെ സ്റ്റൈലസ് ചാർജറുമായി കണക്റ്റ് ചെയ്യുക"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"സ്റ്റൈലസിന്റെ ബാറ്ററി ചാർജ് കുറവാണ്"</string>
<string name="video_camera" msgid="7654002575156149298">"വീഡിയോ ക്യാമറ"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"വ്യക്തിപര ആപ്പിൽ നിന്ന് കോൾ ചെയ്യാനാകില്ല"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് കോളുകൾ ചെയ്യാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ഔദ്യോഗിക ഫോൺ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"റദ്ദാക്കുക"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"ലോക്ക് സ്‌ക്രീൻ ഇഷ്ടാനുസൃതമാക്കൂ"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ലോക്ക് സ്ക്രീൻ ഇഷ്ടാനുസൃതമാക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"വൈഫൈ ലഭ്യമല്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f21d1fd2b93f..1f24255f6fc0 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Дэлгэцийн бичлэгийг хадгалсан"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Харахын тулд товшино уу"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Дэлгэцийн бичлэгийг хадгалахад алдаа гарлаа"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Буцах"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Гэрийн"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Царайг баталгаажууллаа"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Баталгаажсан"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Дуусгахын тулд баталгаажуулахыг товших"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Царайгаар түгжээг тайлсан."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Бүтэн дэлгэцийг томруулах"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Дэлгэцийн нэг хэсгийг томруулах"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Томруулах тохиргоог нээх"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Томруулах тохиргоог хаах"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Хэмжээг өөрчлөхийн тулд булангаас чирнэ үү"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Хөндлөн гүйлгэхийг зөвшөөрөх"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Хэмжээг өөрчлөх"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулж буй <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-н <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ажиллаж байна"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Тоглуулах"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Түр зогсоох"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Өмнөх бичлэг"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Туслах сонсож байна"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Тэмдэглэл хөтлөх"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Мэдрэгч үзгээ цэнэглэгчтэй холбоорой"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Мэдрэгч үзэгний батарей бага байна"</string>
<string name="video_camera" msgid="7654002575156149298">"Видео камер"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Хувийн аппаас залгах боломжгүй"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Танай байгууллага танд зөвхөн ажлын аппуудаас дуудлага хийхийг зөвшөөрдөг"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Ажлын гар утасны апп суулгах"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Цуцлах"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Түгжигдсэн дэлгэцийг өөрчлөх"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Түгжээтэй дэлгэцийг өөрчлөхийн тулд түгжээг тайлна уу"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi боломжгүй байна"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 24407cc412fd..db3585d2787a 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेअर करा"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रेकॉर्डिंग सेव्ह केली"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"पाहण्यासाठी टॅप करा"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रेकॉर्डिंग सेव्ह करताना एरर आली"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
<string name="accessibility_back" msgid="6530104400086152611">"मागे"</string>
<string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"चेहऱ्याने अनलॉक केले आहे."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
@@ -261,7 +261,7 @@
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"नेटवर्क उपलब्ध नाहीत"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"वाय-फाय नेटवर्क उपलब्‍ध नाहीत"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"सुरू करत आहे…"</string>
- <string name="quick_settings_cast_title" msgid="2279220930629235211">"स्क्रीन कास्ट करा"</string>
+ <string name="quick_settings_cast_title" msgid="2279220930629235211">"स्क्रीन कास्ट"</string>
<string name="quick_settings_casting" msgid="1435880708719268055">"कास्ट करत आहे"</string>
<string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"निनावी डिव्हाइस"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"कोणतेही डिव्हाइसेस उपलब्ध नाहीत"</string>
@@ -719,8 +719,8 @@
<string name="right_keycode" msgid="2480715509844798438">"उजवा कीकोड"</string>
<string name="left_icon" msgid="5036278531966897006">"डावे आयकन"</string>
<string name="right_icon" msgid="1103955040645237425">"उजवे आयकन"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"टाइल जोडण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"टाइलची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"टाइल जोडण्यासाठी धरून ठेवून ड्रॅग करा"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"टाइलची पुनर्रचना करण्यासाठी धरून ठेवून ड्रॅग करा"</string>
<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>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फुल स्क्रीन मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"मॅग्निफिकेशन सेटिंग्ज उघडा"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"मॅग्निफिकेशन सेटिंग्ज बंद करा"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"आकार बदलण्यासाठी कोपरा ड्रॅग करा"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरपे स्क्रोल करण्याची अनुमती द्या"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदला"</string>
@@ -906,7 +907,7 @@
<string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> स्थानावर हलवा"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"नियंत्रणे"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"झटपट अ‍ॅक्सेस करण्यासाठी डिव्हाइस नियंत्रणे निवडा"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवून ड्रॅग करा"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"सर्व नियंत्रणे काढून टाकली आहेत"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"बदल सेव्ह केले गेले नाहीत"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"इतर अ‍ॅप्स पहा"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> पैकी <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> रन होत आहे"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"प्ले करा"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"थांबवा"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"मागील गाणे"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ऐकत आहे"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"नोटटेकिंग"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"तुमचे स्टायलस चार्जरशी कनेक्ट करा"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"स्टायलस बॅटरी कमी आहे"</string>
<string name="video_camera" msgid="7654002575156149298">"व्हिडिओ कॅमेरा"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"वैयक्तिक ॲपवरून कॉल करू शकत नाही"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"तुमची संस्था तुम्हाला फक्त work app वरून कॉल करण्याची अनुमती देते"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"कामाशी संबंधित फोन अ‍ॅप इंस्टॉल करा"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"रद्द करा"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"कस्टमाइझ लॉक स्‍क्रीन"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लॉक स्‍क्रीन कस्टमाइझ करण्यासाठी अनलॉक करा"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"वाय-फाय उपलब्ध नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index c26ec6d8858c..6708af6f4fa0 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Kongsi"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Rakaman skrin disimpan"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Ketik untuk lihat"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ralat semasa memadamkan rakaman skrin"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Ralat semasa menyimpan rakaman skrin"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Rumah"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah disahkan"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Disahkan"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketik Sahkan untuk menyelesaikan"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk teruskan."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Dibuka kunci dengan wajah."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Besarkan skrin penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Besarkan sebahagian skrin"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Buka tetapan pembesaran"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Tutup tetapan pembesaran"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Seret sudut untuk mengubah saiz"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Benarkan penatalan pepenjuru"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ubah saiz"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dimainkan daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> daripada <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang dijalankan"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Main"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Jeda"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Lagu sebelumnya"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pembantu sedang mendengar"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pemberitahuan}other{# pemberitahuan}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pengambilan nota"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 554a4470cc22..fff123688b41 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"မျှဝေရန်"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"စကရင်ရိုက်ကူးမှု သိမ်းပြီးပြီ"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ကြည့်ရှုရန် တို့ပါ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ဖန်သားပြင်ရိုက်ကူးမှုကို သိမ်းရာတွင် အမှားရှိသည်"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
<string name="accessibility_back" msgid="6530104400086152611">"နောက်သို့"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ပင်မစာမျက်နှာ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"အတည်ပြုပြီးပြီ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတနှိပ်၍ ရှေ့ဆက်ပါ။"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"မျက်နှာဖြင့် ဖွင့်ထားသည်။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ဖန်သားပြင်အပြည့် ချဲ့သည်"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ချဲ့ခြင်း ဆက်တင်များ ဖွင့်ရန်"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ချဲ့ခြင်း ဆက်တင်များ ပိတ်ရန်"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"အရွယ်အစားပြန်ပြုပြင်ရန် ထောင့်စွန်းကို ဖိဆွဲပါ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ထောင့်ဖြတ် လှိမ့်ခွင့်ပြုရန်"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"အရွယ်အစားပြန်ပြုပြင်ရန်"</string>
@@ -911,7 +912,7 @@
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"အပြောင်းအလဲများကို သိမ်းမထားပါ"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"အခြားအက်ပ်များကိုကြည့်ပါ"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"ပြန်စီရန်"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"သတ်မှတ်ချက်များ ထည့်ရန်"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"ထိန်းချုပ်မှုများ ထည့်ရန်"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"တည်းဖြတ်ခြင်းသို့ ပြန်သွားရန်"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"ထိန်းချုပ်မှုများကို ဖွင့်၍မရပါ။ အက်ပ်ဆက်တင်များ ပြောင်းမထားကြောင်း သေချာစေရန် <xliff:g id="APP">%s</xliff:g> အက်ပ်ကို စစ်ဆေးပါ။"</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"ကိုက်ညီသော ထိန်းချုပ်မှုများကို မရရှိနိုင်ပါ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ထားသည်"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> အနက် <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ပွင့်နေပါသည်"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ဖွင့်ရန်"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ခဏရပ်ရန်"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ယခင် တစ်ပုဒ်"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant နားထောင်နေသည်"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}other{အကြောင်းကြားချက် # ခု}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>၊ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"မှတ်စုလိုက်ခြင်း"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"စတိုင်လပ်စ်ကို အားသွင်းကိရိယာနှင့် ချိတ်ဆက်ခြင်း"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"စတိုင်လပ်စ် ဘက်ထရီ အားနည်းနေသည်"</string>
<string name="video_camera" msgid="7654002575156149298">"ဗီဒီယိုကင်မရာ"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ကိုယ်ရေးသုံးအက်ပ်မှ ဖုန်းဆက်၍မရပါ"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ ဖုန်းဆက်ခွင့်ပြုသည်"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"အလုပ်သုံး ဖုန်းအက်ပ် ထည့်သွင်းရန်"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"မလုပ်တော့"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"လော့ခ်မျက်နှာပြင်စိတ်ကြိုက်လုပ်ရန်"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"လော့ခ်မျက်နှာပြင် စိတ်ကြိုက်လုပ်ရန် ဖွင့်ပါ"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi မရနိုင်ပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 49ea80e19ca1..24f7cb193218 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Skjermopptaket er lagret"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Trykk for å se"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Feil ved sletting av skjermopptaket"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Feil ved lagring av skjermopptaket"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tilbake"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startside"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Låst opp med ansiktet."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstørr hele skjermen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstørr en del av skjermen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Åpne innstillinger for forstørring"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Lukk forstørringsinnstillingene"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dra hjørnet for å endre størrelse"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillat diagonal rulling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Endre størrelse"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Spill av"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Forrige spor"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistenten lytter"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notatskriving"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koble pekepennen til en lader"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Det er lite batteri i pekepennen"</string>
<string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Kan ikke ringe fra personlige apper"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisasjonen din tillater bare at du ringer fra jobbapper"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer en jobbapp på telefonen"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Avbryt"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Tilpass låseskjermen"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Du må låse opp enheten for å tilpasse låseskjermen"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi er ikke tilgjengelig"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index d2087f016ed6..5c6e846683fd 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रिन रेकर्डिङ सेभ गरियो"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"हेर्नका लागि ट्याप गर्नुहोस्"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रिन रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
<string name="accessibility_back" msgid="6530104400086152611">"पछाडि"</string>
<string name="accessibility_home" msgid="5430449841237966217">"गृह"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"अनुहार प्रमाणीकरण गरियो"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"अनुहार प्रयोग गरी अनलक गरियो।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
@@ -275,7 +275,7 @@
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बन्द गर्नुहोस्"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"जोडिएको"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"यन्त्र जडान भयो, ब्याट्रीको चार्ज स्तर <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="quick_settings_connecting" msgid="2381969772953268809">"जडान हुँदै..."</string>
+ <string name="quick_settings_connecting" msgid="2381969772953268809">"कनेक्ट गरिँदै छ..."</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"हटस्पट"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"सक्रिय गर्दै…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"डेटा सेभर सक्रिय छ"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"पूरै स्क्रिन जुम इन गर्नुहोस्"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"जुम इनसम्बन्धी सेटिङ खोल्नुहोस्"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"जुम इन गर्ने सुविधाको सेटिङ बन्द गर्नुहोस्"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"आकार बदल्न कुनाबाट ड्र्याग गर्नुहोस्"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"डायगोनल तरिकाले स्क्रोल गर्ने अनुमति दिनुहोस्"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदल्नुहोस्"</string>
@@ -911,7 +912,7 @@
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"परिवर्तनहरू सुरक्षित गरिएका छैनन्"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"अन्य एपहरू हेर्नुहोस्"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"पुनः मिलाउनुहोस्"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कन्ट्रोलहरू थप्नुहोस्"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कन्ट्रोलहरू हाल्नुहोस्"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"सम्पादन गर्ने स्क्रिनमा फर्कनुहोस्"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"नियन्त्रण सुविधाहरू लोड गर्न सकिएन। <xliff:g id="APP">%s</xliff:g> एपका सेटिङ परिवर्तन गरिएका छैनन् भन्ने कुरा सुनिश्चित गर्न उक्त एप जाँच्नुहोस्।"</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"मिल्दा नियन्त्रण सुविधाहरू उपलब्ध छैनन्"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> मध्ये <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> चलिरहेको छ"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"प्ले गर्नुहोस्"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"पज गर्नुहोस्"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"अघिल्लो ट्रयाक"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"सहायकले सुनिरहेको छ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"टिपोट गर्ने कार्य"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"आफ्नो स्टाइलस चार्जरमा कनेक्ट गर्नुहोस्"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलसको ब्याट्री लो छ"</string>
<string name="video_camera" msgid="7654002575156149298">"भिडियो क्यामेरा"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"व्यक्तिगत एपमार्फत कल गर्न मिल्दैन"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र कल गर्ने अनुमति दिएको छ"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"कामसम्बन्धी फोन एप इन्स्टल गर्नुहोस्"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"रद्द गर्नुहोस्"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"लक स्क्रिन कस्टमाइज गर्नुहोस्"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लक स्क्रिन कस्टमाइज गर्न अनलक गर्नुहोस्"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi उपलब्ध छैन"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 5efcef376817..99311e3d1e1b 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -100,4 +100,8 @@
<color name="accessibility_floating_menu_message_text">@*android:color/primary_text_default_material_dark</color>
<color name="people_tile_background">@color/material_dynamic_secondary20</color>
+
+ <!-- Internet Dialog -->
+ <color name="connected_network_primary_color">@color/material_dynamic_primary80</color>
+ <color name="connected_network_secondary_color">@color/material_dynamic_secondary80</color>
</resources>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index 99bc794547f2..b6971d3c1fa4 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -58,17 +58,13 @@
<style name="TextAppearance.InternetDialog.Active">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="android:textColor">@color/material_dynamic_primary80</item>
<item name="android:textDirection">locale</item>
</style>
<style name="TextAppearance.InternetDialog.Secondary.Active">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
- </style>
-
- <style name="InternetDialog.Divider.Active">
- <item name="android:background">?android:attr/textColorSecondaryInverse</item>
+ <item name="android:textColor">@color/material_dynamic_secondary80</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 2d4c8ffb6a81..c4d6f685383c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Delen"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Schermopname opgeslagen"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekijken"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fout bij verwijderen van schermopname"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Fout bij opslaan van schermopname"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Terug"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startscherm"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gezicht geverifieerd"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestigd"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestigen om te voltooien"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Ontgrendeld via gezicht."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Volledig scherm vergroten"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Deel van het scherm vergroten"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Instellingen voor vergroting openen"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Instellingen voor vergroting sluiten"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Sleep een hoek om het formaat te wijzigen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonaal scrollen toestaan"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Formaat aanpassen"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wordt afgespeeld via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is actief"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Afspelen"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauzeren"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Vorige track"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"De Assistent luistert"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Aantekeningen maken"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 4942f193b6f4..428e42ba3c53 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -105,7 +105,7 @@
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"ଅଡିଓ ରେକର୍ଡ କରନ୍ତୁ"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"ଡିଭାଇସ୍ ଅଡିଓ"</string>
- <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ, ଯେପରିକି ସଙ୍ଗୀତ, କଲ୍ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ"</string>
+ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ମ୍ୟୁଜିକ, କଲ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ ପରି ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"ମାଇକ୍ରୋଫୋନ"</string>
<string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"ଡିଭାଇସ୍ ଅଡିଓ ଏବଂ ମାଇକ୍ରୋଫୋନ୍"</string>
<string name="screenrecord_continue" msgid="4055347133700593164">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍‍ କରନ୍ତୁ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ କରାଯାଇଛି"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ଡିଲିଟ୍‍ କରିବାରେ ତ୍ରୁଟି"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ଫେରନ୍ତୁ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ହୋମ"</string>
@@ -134,7 +134,7 @@
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
<string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string>
- <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
@@ -256,7 +256,7 @@
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"ମିଡିଆ ଡିଭାଇସ୍‌"</string>
<string name="quick_settings_user_title" msgid="8673045967216204537">"ଉପଯୋଗକର୍ତ୍ତା‌"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string>
- <string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟରନେଟ୍"</string>
+ <string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟରନେଟ"</string>
<string name="quick_settings_networks_available" msgid="1875138606855420438">"ନେଟୱାର୍କଗୁଡ଼ିକ ଉପଲବ୍ଧ"</string>
<string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"କୌଣସି ୱାଇ-ଫାଇ ନେଟ୍‌ୱର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -528,7 +528,7 @@
<string name="enable_demo_mode" msgid="3180345364745966431">"ଡେମୋ ମୋଡ୍ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="show_demo_mode" msgid="3677956462273059726">"ଡେମୋ ମୋଡ୍‍ ଦେଖାନ୍ତୁ"</string>
<string name="status_bar_ethernet" msgid="5690979758988647484">"ଇଥରନେଟ୍‌"</string>
- <string name="status_bar_alarm" msgid="87160847643623352">"ଆଲାର୍ମ"</string>
+ <string name="status_bar_alarm" msgid="87160847643623352">"ଆଲାରାମ"</string>
<string name="wallet_title" msgid="5369767670735827105">"ୱାଲେଟ୍"</string>
<string name="wallet_empty_state_label" msgid="7776761245237530394">"ଆପଣଙ୍କ ଫୋନ୍ ମାଧ୍ୟମରେ ଆହୁରି ଶୀଘ୍ର, ଅଧିକ ସୁରକ୍ଷିତ କ୍ରୟ କରିବା ପାଇଁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="wallet_app_button_label" msgid="7123784239111190992">"ସବୁ ଦେଖାନ୍ତୁ"</string>
@@ -626,7 +626,7 @@
<string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"ଫାଷ୍ଟ ଫର୍‌ୱାର୍ଡ"</string>
<string name="keyboard_key_page_up" msgid="173914303254199845">"ଉପର ପୃଷ୍ଠା"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"ତଳ ପୃଷ୍ଠା"</string>
- <string name="keyboard_key_forward_del" msgid="5325501825762733459">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="keyboard_key_forward_del" msgid="5325501825762733459">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"ହୋମ"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"ସମାପ୍ତ"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"ଇନ୍‌ସର୍ଟ"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ମାଗ୍ନିଫିକେସନ ସେଟିଂସ ଖୋଲନ୍ତୁ"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ମେଗ୍ନିଫିକେସନ ସେଟିଂସକୁ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ରିସାଇଜ କରିବା ପାଇଁ କୋଣକୁ ଡ୍ରାଗ କରନ୍ତୁ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ଡାଏଗୋନାଲ ସ୍କ୍ରୋଲିଂକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ରିସାଇଜ କରନ୍ତୁ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ରୁ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ଚଲାନ୍ତୁ"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ବିରତ କରନ୍ତୁ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ପୂର୍ବବର୍ତ୍ତୀ ଟ୍ରାକ"</string>
@@ -1055,7 +1057,7 @@
<string name="mobile_data_connection_active" msgid="944490013299018227">"ସଂଯୋଗ କରାଯାଇଛି"</string>
<string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ଅସ୍ଥାୟୀ ରୂପେ କନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="mobile_data_poor_connection" msgid="819617772268371434">"ଦୁର୍ବଳ କନେକ୍ସନ"</string>
- <string name="mobile_data_off_summary" msgid="3663995422004150567">"ମୋବାଇଲ ଡାଟା ସ୍ୱତଃ-ସଂଯୋଗ ହେବ ନାହିଁ"</string>
+ <string name="mobile_data_off_summary" msgid="3663995422004150567">"ମୋବାଇଲ ଡାଟା ସ୍ୱତଃ-କନେକ୍ଟ ହେବ ନାହିଁ"</string>
<string name="mobile_data_no_connection" msgid="1713872434869947377">"ସଂଯୋଗ ନାହିଁ"</string>
<string name="non_carrier_network_unavailable" msgid="770049357024492372">"ଅନ୍ୟ କୌଣସି ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="all_network_unavailable" msgid="4112774339909373349">"କୌଣସି ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ଶୁଣୁଛି"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}other{#ଟି ବିଜ୍ଞପ୍ତି}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"ନୋଟଟେକିଂ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ଏକ ଚାର୍ଜର ସହ ଆପଣଙ୍କ ଷ୍ଟାଇଲସକୁ କନେକ୍ଟ କରନ୍ତୁ"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"ଷ୍ଟାଇଲସ ବେଟେରୀର ଚାର୍ଜ କମ ଅଛି"</string>
<string name="video_camera" msgid="7654002575156149298">"ଭିଡିଓ କେମେରା"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ଏକ ବ୍ୟକ୍ତିଗତ ଆପରୁ କଲ କରିପାରିବେ ନାହିଁ"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ଏକ ୱାର୍କ ଫୋନ ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅନଲକ କରନ୍ତୁ"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 8a93c8cbd7f7..cda538fdbb44 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"ਸਾਂਝਾ ਕਰੋ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ਪਿੱਛੇ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ਘਰ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਿਰਤ ਹੋਇਆ"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
@@ -275,7 +275,7 @@
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ਬੰਦ ਕਰੋ"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"ਕਨੈਕਟ ਕੀਤੀ ਗਈ, ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <string name="quick_settings_connecting" msgid="2381969772953268809">"ਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string>
+ <string name="quick_settings_connecting" msgid="2381969772953268809">"ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ਹੌਟਸਪੌਟ"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ਸਕ੍ਰੀਨ ਦੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ ਬੰਦ ਕਰੋ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ਆਕਾਰ ਬਦਲਣ ਲਈ ਕੋਨਾ ਘਸੀਟੋ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ਟੇਡੀ ਦਿਸ਼ਾ ਵਿੱਚ ਸਕ੍ਰੋਲ ਕਰਨ ਦਿਓ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ਆਕਾਰ ਬਦਲੋ"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ਵਿੱਚੋਂ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ਚਲਾਓ"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"ਰੋਕੋ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ਪਿਛਲਾ ਟਰੈਕ"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ਸੁਣ ਰਹੀ ਹੈ"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ਸੂਚਨਾ}one{# ਸੂਚਨਾ}other{# ਸੂਚਨਾਵਾਂ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"ਨੋਟ ਬਣਾਉਣਾ"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ਆਪਣੇ ਸਟਾਈਲਸ ਨੂੰ ਚਾਰਜਰ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"ਸਟਾਈਲਸ ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ"</string>
<string name="video_camera" msgid="7654002575156149298">"ਵੀਡੀਓ ਕੈਮਰਾ"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ਕਿਸੇ ਨਿੱਜੀ ਐਪ ਤੋਂ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ਕੰਮ ਸੰਬੰਧੀ ਫ਼ੋਨ ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"ਰੱਦ ਕਰੋ"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d77d1906483f..f857641d5046 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -103,7 +103,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Podczas nagrywania Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Podczas nagrywania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Zacznij nagrywać"</string>
- <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagraj dźwięk"</string>
+ <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagrywaj dźwięk"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki z urządzenia"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Dźwięki odtwarzane na urządzeniu, na przykład muzyka, połączenia i dzwonki"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Zapisano nagranie zawartości ekranu"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Kliknij, aby wyświetlić"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Podczas zapisywania nagrania ekranu wystąpił błąd"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Wróć"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ekran główny"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Twarz rozpoznana"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potwierdzono"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Aby zakończyć, kliknij Potwierdź"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odblokowano skanem twarzy. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Odblokowano skanem twarzy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Powiększanie pełnego ekranu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Powiększ część ekranu"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otwórz ustawienia powiększenia"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zamknij ustawienia powiększenia"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Przeciągnij róg, aby zmienić rozmiar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Zezwalaj na przewijanie poprzeczne"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmień rozmiar"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Aplikacja <xliff:g id="APP_LABEL">%3$s</xliff:g> odtwarza utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Odtwórz"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Wstrzymaj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Poprzedni utwór"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asystent słucha"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notatki"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string>
@@ -1118,7 +1123,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Zezwolić aplikacji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na dostęp do wszystkich dzienników urządzenia?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Zezwól na jednorazowy dostęp"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nie zezwalaj"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie mogła korzystać z własnych. Producent urządzenia nadal będzie mógł używać niektórych dzienników na urządzeniu."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie mogła korzystać z własnych. Producent urządzenia nadal będzie mógł używać niektórych dzienników lub informacji na urządzeniu."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Więcej informacji"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Więcej informacji: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Podłącz rysik do ładowarki"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Słaba bateria w rysiku"</string>
<string name="video_camera" msgid="7654002575156149298">"Kamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nie można nawiązać połączenia z aplikacji osobistej"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Twoja organizacja zezwala na nawiązywanie połączeń tylko z aplikacji służbowych"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Zainstaluj służbową aplikację telefonu"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Anuluj"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Dostosuj ekran blokady"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Odblokuj, aby dostosować ekran blokady"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Sieć Wi-Fi jest niedostępna"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index f74985fadcd7..ea6ad58c825a 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -108,8 +108,8 @@
</string-array>
<string-array name="tile_states_work">
<item msgid="389523503690414094">"Niedostępny"</item>
- <item msgid="8045580926543311193">"Wyłączony"</item>
- <item msgid="4913460972266982499">"Włączony"</item>
+ <item msgid="8045580926543311193">"Wyłączono"</item>
+ <item msgid="4913460972266982499">"Włączono"</item>
</string-array>
<string-array name="tile_states_cast">
<item msgid="6032026038702435350">"Niedostępny"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 8b21923150be..e73fba7d6e3b 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Desbloqueado pelo rosto."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
@@ -414,7 +414,7 @@
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Início"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
- <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
+ <string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir as configurações de ampliação"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Fechar configurações de ampliação"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arraste o canto para redimensionar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Iniciar"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Google Assistente está ouvindo"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}many{# notificações}other{# notificações}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Anotações"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1daa1def3e94..ef0ae9a8e633 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de ecrã guardada."</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao eliminar a gravação de ecrã."</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao guardar a gravação de ecrã"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
<string name="accessibility_back" msgid="6530104400086152611">"Anterior"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em Confirmar para concluir."</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueio com a face. Prima o ícone de desb. p/ continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Desbloqueado com o rosto."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar o ecrã inteiro"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte do ecrã"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir definições de ampliação"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Fechar definições de ampliação"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastar o canto para redimensionar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir deslocamento da página na diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
@@ -907,7 +908,7 @@
<string name="controls_favorite_default_title" msgid="967742178688938137">"Controlos"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"Escolha os controlos de dispositivos para aceder rapidamente"</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Toque sem soltar e arraste para reorganizar os controlos"</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"Todos os controlos foram removidos."</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"Todos os controlos foram removidos"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Alterações não guardadas."</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Ver outras apps"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Reorganizar"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> em reprodução a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> em execução"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Reproduzir"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -1065,7 +1067,7 @@
<string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"A procurar redes…"</string>
<string name="wifi_failed_connect_message" msgid="4161863112079000071">"Não foi possível estabelecer ligação à rede"</string>
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por agora, o Wi-Fi não irá estabelecer lig. automaticamente"</string>
- <string name="see_all_networks" msgid="3773666844913168122">"Veja tudo"</string>
+ <string name="see_all_networks" msgid="3773666844913168122">"Ver tudo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para mudar de rede, desligue a Ethernet"</string>
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para melhorar a experiência do dispositivo, as apps e os serviços podem continuar a procurar redes Wi-Fi em qualquer altura, mesmo quando o Wi-Fi está desativado. Pode alterar esta opção nas definições de procura de Wi-Fi. "<annotation id="link">"Alterar"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desativar o modo de avião"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Assistente está a ouvir"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}many{# notificações}other{# notificações}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Tomar notas"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8b21923150be..e73fba7d6e3b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Desbloqueado pelo rosto."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
@@ -414,7 +414,7 @@
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Início"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
- <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
+ <string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir as configurações de ampliação"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Fechar configurações de ampliação"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arraste o canto para redimensionar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Iniciar"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Google Assistente está ouvindo"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}many{# notificações}other{# notificações}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Anotações"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index fc3b1e8693ea..900b1f9fd248 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Trimite"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Înregistrarea ecranului a fost salvată"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Atinge pentru a afișa"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Eroare la ștergerea înregistrării ecranului"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Eroare la salvarea înregistrării ecranului"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Înapoi"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ecranul de pornire"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Chip autentificat"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Atinge Confirm pentru a finaliza"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Deblocat facial. Apasă pictograma Deblocare ca să continui."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"S-a deblocat folosind fața."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apasă pentru a continua."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Mărește tot ecranul"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Mărește o parte a ecranului"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Deschide setările pentru mărire"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Închide setările de mărire"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Trage de colț pentru a redimensiona"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permite derularea pe diagonală"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionează"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se redă în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> din <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Redă"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Întrerupe"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Melodia anterioară"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistentul ascultă"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificare}few{# notificări}other{# de notificări}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Notetaking"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Se difuzează"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Oprești transmisia <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Dacă transmiți <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbi ieșirea, transmisia actuală se va opri"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 83ed38ba8ca3..6ad3402011e3 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Видео с экрана сохранено"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не удалось удалить запись видео с экрана"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Не удалось сохранить запись видео с экрана."</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Главный экран"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицо распознано"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Подтверждено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Нажмите \"Подтвердить\""</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Разблокировано сканированием лица."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличение всего экрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличить часть экрана"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Открыть настройки увеличения"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Закрыть настройки увеличения"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Потяните за угол, чтобы изменить размер"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешить прокручивать по диагонали"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Изменить размер"</string>
@@ -905,7 +906,7 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"удалить из избранного"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Переместить на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Элементы управления"</string>
- <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Выберите виджеты управления устройствами для быстрого доступа"</string>
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Выберите виджеты управления устройствами для быстрого доступа."</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Чтобы изменить порядок виджетов, перетащите их."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Все виджеты управления удалены."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Изменения не сохранены."</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Воспроизводится медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\"."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> из <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запущено"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Воспроизвести"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Приостановить"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Предыдущий трек"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Ассистент вас слушает"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Создание заметок"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляция"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Остановить трансляцию \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index fe1feb9262e1..fd07fa769937 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"බෙදා ගන්න"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"තිර පටිගත කිරීම සුරකින ලදී"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"බැලීමට තට්ටු කරන්න"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"තිර පටිගත කිරීම සුරැකීමේ දෝෂයකි"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
<string name="accessibility_back" msgid="6530104400086152611">"ආපසු"</string>
<string name="accessibility_home" msgid="5430449841237966217">"මුල් පිටුව"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"මුහුණ සත්‍යාපන කළා"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"තහවුරු කළා"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"මුහුණ මගින් අගුලු හරින ලදි. දිගටම කරගෙන යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"මුහුණ මගින් අගුළු හරින ලදි."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"පූර්ණ තිරය විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"තිරයේ කොටසක් විශාලනය කරන්න"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"විශාලන සැකසීම් විවෘත කරන්න"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"විශාලන සැකසීම් වසන්න"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ප්‍රමාණය වෙනස් කිරීමට කොන අදින්න"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"විකර්ණ අනුචලනයට ඉඩ දෙන්න"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ප්‍රතිප්‍රමාණය කරන්න"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> ගීතය <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් ධාවනය වෙමින් පවතී"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>කින් <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාවනය වේ"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"වාදනය කරන්න"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"විරාම ගන්වන්න"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"පෙර ඛණ්ඩය"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"සහයක සවන් දෙයි"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{දැනුම්දීම් #ක්}one{දැනුම්දීම් #ක්}other{දැනුම්දීම් #ක්}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"සටහන් කර ගැනීම"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්‍රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c1de994c472e..51f166a054ec 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka bola uložená"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Pri ukladaní nahrávky obrazovky sa vyskytla chyba"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Späť"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Plocha"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Tvár bola overená"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrdené"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Overenie dokončíte klepnutím na Potvrdiť"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odomknuté tvárou. Pokračujte klepnutím na ikonu odomknutia"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Odomknuté tvárou."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
@@ -720,7 +720,7 @@
<string name="left_icon" msgid="5036278531966897006">"Ľavá ikona"</string>
<string name="right_icon" msgid="1103955040645237425">"Pravá ikona"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"Pridržaním a presunutím pridáte karty"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Dlaždice môžete usporiadať pridržaním a presunutím"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Karty môžete usporiadať pridržaním a presunutím"</string>
<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>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zväčšenie celej obrazovky"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zväčšiť časť obrazovky"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvoriť nastavenia zväčšenia"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zavrieť nastavenia zväčšenia"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Veľkosť zmeníte presunutím rohu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povoliť diagonálne posúvanie"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmeniť veľkosť"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sa prehráva z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Prehrať"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pozastaviť"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Predchádzajúca skladba"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent počúva"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Zapisovanie poznámok"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysiela"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index f8235c127a3b..51f4c4e05706 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Snemanje zaslona je shranjeno"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Dotaknite se za ogled."</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Napaka pri brisanju videoposnetka zaslona"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Napaka pri shranjevanju posnetka zaslona"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nazaj"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Začetni zaslon"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Pristnost obraza je potrjena"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potrjeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Za dokončanje se dotaknite »Potrdite«"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odklenjeno z obrazom. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Odklenjeno z obrazom."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povečanje celotnega zaslona"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povečava dela zaslona"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Odpri nastavitve povečave"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Zapri nastavitve povečave"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Povlecite vogal, da spremenite velikost."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dovoli diagonalno pomikanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Spremeni velikost"</string>
@@ -905,13 +906,13 @@
<string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"odstranitev iz priljubljenih"</string>
<string name="accessibility_control_move" msgid="8980344493796647792">"Premakni na položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrolniki"</string>
- <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Izberite kontrolnike naprave, do katerih želite hitro dostopati."</string>
+ <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Izberite kontrolnike naprav, do katerih želite hitro dostopati."</string>
<string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite in povlecite, da prerazporedite kontrolnike."</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Vsi kontrolniki so bili odstranjeni."</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Spremembe niso shranjene"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Prikaz drugih aplikacij"</string>
- <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Razvrščanje"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Dodajte kontrolnike"</string>
+ <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Razvrsti"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Dodaj kontrolnike"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Nazaj na urejanje"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrolnikov ni bilo mogoče naložiti. Preverite aplikacijo <xliff:g id="APP">%s</xliff:g> in se prepričajte, da se njene nastavitve niso spremenile."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Združljivi kontrolniki niso na voljo"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se predvaja iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Predvajaj"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Začasno zaustavi"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prejšnja skladba"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pomočnik posluša."</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Ustvarjanje zapiskov"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisalo s polnilnikom."</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"Skoraj prazna baterija pisala"</string>
<string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ni mogoče klicati iz osebne aplikacije."</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organizacija vam omogoča klicanje samo iz delovnih aplikacij."</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Namestite delovno aplikacijo za telefon"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Prekliči"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Prilagajanje zaklenjenega zaslona"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Odklenite za prilagajanje zaklenjenega zaslona"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ni na voljo."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 8303ac46e70c..9905a6f381ab 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ndaj"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Regjistrimi i ekranit u ruajt"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Trokit për të parë"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Gabim gjatë ruajtjes së regjistrimit të ekranit"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Faqja bazë"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Fytyra u vërtetua"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Konfirmuar"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trokit \"Konfirmo\" për ta përfunduar"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"U shkyç me fytyrë."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zmadho ekranin e plotë"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zmadho një pjesë të ekranit"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Hap cilësimet e zmadhimit"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Mbyll cilësimet e zmadhimit"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Zvarrit këndin për të ndryshuar përmasat"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Lejo lëvizjen diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ndrysho përmasat"</string>
@@ -906,7 +907,7 @@
<string name="accessibility_control_move" msgid="8980344493796647792">"Zhvendose te pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrollet"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"Zgjidh kontrollet e pajisjes për të pasur qasje me shpejtësi"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mbaje të shtypur dhe zvarrit për të risistemuar kontrollet"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mbaje shtypur dhe zvarrit për të riorganizuar kontrollet"</string>
<string name="controls_favorite_removed" msgid="5276978408529217272">"Të gjitha kontrollet u hoqën"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ndryshimet nuk u ruajtën"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Shiko aplikacionet e tjera"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> po luhet nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> nga <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> po ekzekutohet"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Luaj"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Vendos në pauzë"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Pjesa muzikore e mëparshme"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"\"Asistenti\" po dëgjon"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# njoftim}other{# njoftime}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Mbajtja e shënimeve"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Po transmeton"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Të ndalohet transmetimi i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 45f63bf8e2e8..b8e1355dfb25 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -48,7 +48,7 @@
</string-array>
<string-array name="tile_states_battery">
<item msgid="6311253873330062961">"Nuk ofrohet"</item>
- <item msgid="7838121007534579872">"Joaktiv"</item>
+ <item msgid="7838121007534579872">"Joaktive"</item>
<item msgid="1578872232501319194">"Aktiv"</item>
</string-array>
<string-array name="tile_states_dnd">
@@ -59,7 +59,7 @@
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nuk ofrohet"</item>
<item msgid="5044688398303285224">"Joaktiv"</item>
- <item msgid="8527389108867454098">"Aktiv"</item>
+ <item msgid="8527389108867454098">"Aktive"</item>
</string-array>
<string-array name="tile_states_rotation">
<item msgid="4578491772376121579">"Nuk ofrohet"</item>
@@ -88,13 +88,13 @@
</string-array>
<string-array name="tile_states_color_correction">
<item msgid="2840507878437297682">"Nuk ofrohet"</item>
- <item msgid="1909756493418256167">"Joaktiv"</item>
- <item msgid="4531508423703413340">"Aktiv"</item>
+ <item msgid="1909756493418256167">"Joaktive"</item>
+ <item msgid="4531508423703413340">"Aktive"</item>
</string-array>
<string-array name="tile_states_inversion">
<item msgid="3638187931191394628">"Nuk ofrohet"</item>
- <item msgid="9103697205127645916">"Joaktiv"</item>
- <item msgid="8067744885820618230">"Aktiv"</item>
+ <item msgid="9103697205127645916">"Joaktive"</item>
+ <item msgid="8067744885820618230">"Aktive"</item>
</string-array>
<string-array name="tile_states_saver">
<item msgid="39714521631367660">"Nuk ofrohet"</item>
@@ -108,7 +108,7 @@
</string-array>
<string-array name="tile_states_work">
<item msgid="389523503690414094">"Nuk ofrohet"</item>
- <item msgid="8045580926543311193">"Joaktiv"</item>
+ <item msgid="8045580926543311193">"Joaktive"</item>
<item msgid="4913460972266982499">"Aktiv"</item>
</string-array>
<string-array name="tile_states_cast">
@@ -123,13 +123,13 @@
</string-array>
<string-array name="tile_states_screenrecord">
<item msgid="1085836626613341403">"Nuk ofrohet"</item>
- <item msgid="8259411607272330225">"Joaktiv"</item>
+ <item msgid="8259411607272330225">"Joaktive"</item>
<item msgid="578444932039713369">"Aktiv"</item>
</string-array>
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nuk ofrohet"</item>
- <item msgid="8707481475312432575">"Joaktiv"</item>
- <item msgid="8031106212477483874">"Aktiv"</item>
+ <item msgid="8707481475312432575">"Joaktive"</item>
+ <item msgid="8031106212477483874">"Aktive"</item>
</string-array>
<string-array name="tile_states_reduce_brightness">
<item msgid="1839836132729571766">"Nuk ofrohet"</item>
@@ -144,7 +144,7 @@
<string-array name="tile_states_mictoggle">
<item msgid="6895831614067195493">"Nuk ofrohet"</item>
<item msgid="3296179158646568218">"Joaktiv"</item>
- <item msgid="8998632451221157987">"Aktiv"</item>
+ <item msgid="8998632451221157987">"Aktive"</item>
</string-array>
<string-array name="tile_states_controls">
<item msgid="8199009425335668294">"Nuk ofrohet"</item>
@@ -158,13 +158,13 @@
</string-array>
<string-array name="tile_states_qr_code_scanner">
<item msgid="7435143266149257618">"Nuk ofrohet"</item>
- <item msgid="3301403109049256043">"Joaktiv"</item>
- <item msgid="8878684975184010135">"Aktiv"</item>
+ <item msgid="3301403109049256043">"Joaktive"</item>
+ <item msgid="8878684975184010135">"Aktive"</item>
</string-array>
<string-array name="tile_states_alarm">
<item msgid="4936533380177298776">"Nuk ofrohet"</item>
<item msgid="2710157085538036590">"Joaktiv"</item>
- <item msgid="7809470840976856149">"Aktiv"</item>
+ <item msgid="7809470840976856149">"Aktive"</item>
</string-array>
<string-array name="tile_states_onehanded">
<item msgid="8189342855739930015">"Nuk ofrohet"</item>
@@ -173,12 +173,12 @@
</string-array>
<string-array name="tile_states_dream">
<item msgid="6184819793571079513">"Nuk ofrohet"</item>
- <item msgid="8014986104355098744">"Joaktiv"</item>
- <item msgid="5966994759929723339">"Aktiv"</item>
+ <item msgid="8014986104355098744">"Joaktive"</item>
+ <item msgid="5966994759929723339">"Aktive"</item>
</string-array>
<string-array name="tile_states_font_scaling">
<item msgid="3173069902082305985">"Nuk ofrohet"</item>
- <item msgid="2478289035899842865">"Joaktiv"</item>
- <item msgid="5137565285664080143">"Aktiv"</item>
+ <item msgid="2478289035899842865">"Joaktive"</item>
+ <item msgid="5137565285664080143">"Aktive"</item>
</string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4933c4bdd918..5885c10c6b96 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Снимак екрана је сачуван"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при чувању снимка екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Почетна"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Откључано је лицем. Притисните икону откључавања за наставак"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Откључано је лицем."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
@@ -209,7 +209,7 @@
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Прозор са обавештењима."</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брза подешавања."</string>
<string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Брза подешавања и трака са обавештењима."</string>
- <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран."</string>
+ <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран"</string>
<string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Закључан екран за посао"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"потпуна тишина"</string>
@@ -784,7 +784,7 @@
<string name="tuner_right" msgid="8247571132790812149">"Стрелица удесно"</string>
<string name="tuner_menu" msgid="363690665924769420">"Мени"</string>
<string name="tuner_app" msgid="6949280415826686972">"Апликација <xliff:g id="APP">%1$s</xliff:g>"</string>
- <string name="notification_channel_alerts" msgid="3385787053375150046">"Обавештења"</string>
+ <string name="notification_channel_alerts" msgid="3385787053375150046">"Упозорења"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"Батерија"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"Снимци екрана"</string>
<string name="notification_channel_instant" msgid="7556135423486752680">"Инстант апликације"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Отвори подешавања увећања"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Затвори подешавања увећања"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Превуците угао да бисте променили величину"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволи дијагонално скроловање"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Промени величину"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је покренута"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Пусти"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Паузирај"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песма"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Помоћник слуша"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Прављење бележака"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e87bda6ab71f..be35743625ce 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Dela"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Skärminspelning sparad"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Tryck för att visa"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Det gick inte att radera skärminspelningen"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Det gick inte att spara skärminspelningen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Tillbaka"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Startsida"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet har autentiserats"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekräftat"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att fortsätta."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Upplåst med ansiktslås."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Förstora hela skärmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Förstora en del av skärmen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Öppna inställningarna för förstoring"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Stäng inställningarna för förstoring"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dra i hörnet för att ändra storlek"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillåt diagonal scrollning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ändra storlek"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spelas upp från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Spela upp"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Föregående spår"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistenten lyssnar"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Anteckningar"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index d71bd15afe51..fae139cb32be 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Imehifadhi rekodi ya skrini"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya skrini"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Nyuma"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Nyumbani"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Uso umethibitishwa"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Imethibitishwa"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Gusa Thibitisha ili ukamilishe"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili uendelee."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Imefunguka kwa kutumia uso wako."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Kuza skrini nzima"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Kuza sehemu ya skrini"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Fungua mipangilio ya ukuzaji"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Funga mipangilio ya ukuzaji"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Buruta kona ili ubadilishe ukubwa"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Ruhusu usogezaji wa kimshazari"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Badilisha ukubwa"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> unacheza katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> kati ya <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumika"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Cheza"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Simamisha"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Wimbo uliotangulia"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Programu ya Mratibu inasikiliza"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Kuandika vidokezo"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index cce3de3caf1b..049224526781 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"பகிர்"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"ஸ்கிரீன் ரெக்கார்டிங் சேமிக்கப்பட்டது"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"பார்க்கத் தட்டவும்"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"ஸ்கிரீன் ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
<string name="accessibility_back" msgid="6530104400086152611">"பின்செல்"</string>
<string name="accessibility_home" msgid="5430449841237966217">"முகப்பு"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"முகம் அங்கீகரிக்கப்பட்டது"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர, அன்லாக் ஐகானை அழுத்துக."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"முகம் மூலம் அன்லாக் செய்யப்பட்டது."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"முழுத்திரையைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"திரையின் ஒரு பகுதியைப் பெரிதாக்கும்"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"பெரிதாக்கல் அமைப்புகளைத் திற"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"பெரிதாக்கல் அமைப்புகளை மூடுக"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"அளவை மாற்ற மூலையை இழுக்கவும்"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"குறுக்கே ஸ்க்ரோல் செய்வதை அனுமதி"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"அளவை மாற்று"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடல் <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேயாகிறது"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> இயங்கிக் கொண்டிருக்கிறது"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"பிளே செய்"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"இடைநிறுத்து"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"முந்தைய டிராக்"</string>
@@ -970,7 +972,7 @@
<string name="controls_error_generic" msgid="352500456918362905">"நிலையைக் காட்ட முடியவில்லை"</string>
<string name="controls_error_failed" msgid="960228639198558525">"பிழை, மீண்டும் முயலவும்"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"கட்டுப்பாடுகளைச் சேர்த்தல்"</string>
- <string name="controls_menu_edit" msgid="890623986951347062">"கட்டுப்பாடுகளை மாற்றுதல்"</string>
+ <string name="controls_menu_edit" msgid="890623986951347062">"கட்டுப்பாடுகளை மாற்றுக"</string>
<string name="controls_menu_add_another_app" msgid="8661172304650786705">"ஆப்ஸைச் சேர்"</string>
<string name="controls_menu_remove" msgid="3006525275966023468">"ஆப்ஸை அகற்று"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"அவுட்புட்களைச் சேர்த்தல்"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant கேட்டுக்கொண்டிருக்கிறது"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}other{# அறிவிப்புகள்}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"குறிப்பெடுத்தல்"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"உங்கள் ஸ்டைலஸைச் சார்ஜருடன் இணையுங்கள்"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"ஸ்டைலஸின் பேட்டரி குறைவாக உள்ளது"</string>
<string name="video_camera" msgid="7654002575156149298">"வீடியோ கேமரா"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"தனிப்பட்ட ஆப்ஸில் இருந்து அழைக்க முடியாது"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே அழைக்க உங்களை அனுமதிக்கிறது"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"பணி மொபைல் ஆப்ஸை நிறுவு"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"ரத்துசெய்"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"பூட்டுத் திரையை பிரத்தியேகமாக்கு"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"பூட்டுத் திரையைப் பிரத்தியேகப்படுத்த அன்லாக் செய்யுங்கள்"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"வைஃபை கிடைக்கவில்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index ab40192918cd..4572face3f38 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,7 +103,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్‌పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"మీరు ఏదైనా యాప్‌ను రికార్డ్ చేసేటప్పుడు, ఆ యాప్‌లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"రికార్డింగ్‌ను ప్రారంభించండి"</string>
- <string name="screenrecord_audio_label" msgid="6183558856175159629">"ఆడియోను రికార్డ్ చేయి"</string>
+ <string name="screenrecord_audio_label" msgid="6183558856175159629">"ఆడియోను రికార్డ్ చేయండి"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"పరికరం ఆడియో"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"మీ పరికరం నుండి వచ్చే మ్యూజిక్, కాల్స్‌, రింగ్‌టోన్‌ల వంటి ధ్వనులు"</string>
<string name="screenrecord_mic_label" msgid="2111264835791332350">"మైక్రోఫోన్"</string>
@@ -111,12 +111,12 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"ప్రారంభించండి"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"స్క్రీన్ రికార్డింగ్ చేయబడుతోంది"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"స్క్రీన్, ఆడియో రికార్డింగ్ చేయబడుతున్నాయి"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్‌పై తాకే స్థానాలను చూపు"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్‌పై తాకే స్థానాలను చూపండి"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"ఆపివేయి"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"షేర్ చేయి"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"చూడటానికి ట్యాప్ చేయండి"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"స్క్రీన్ రికార్డింగ్‌ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"స్క్రీన్ రికార్డింగ్‌ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
<string name="accessibility_back" msgid="6530104400086152611">"వెనుకకు"</string>
<string name="accessibility_home" msgid="5430449841237966217">"హోమ్"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ముఖం ప్రామాణీకరించబడింది"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
@@ -150,7 +150,7 @@
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించండి"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించండి"</string>
<string name="biometric_dialog_use_password" msgid="3445033859393474779">"పాస్‌వర్డ్‌ను ఉపయోగించండి"</string>
- <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"పిన్ తప్పు"</string>
+ <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"PIN తప్పు"</string>
<string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ఆకృతి తప్పు"</string>
<string name="biometric_dialog_wrong_password" msgid="69477929306843790">"పాస్‌వర్డ్ తప్పు"</string>
<string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు.\n<xliff:g id="NUMBER">%d</xliff:g> సెకన్ల తర్వాత మళ్లీ ట్రై చేయండి."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"మ్యాగ్నిఫికేషన్ సెట్టింగ్‌లను తెరవండి"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"మాగ్నిఫికేషన్ సెట్టింగ్‌లను మూసివేయండి"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"సైజ్ మార్చడానికి మూలను లాగండి"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"డయాగనల్ స్క్రోలింగ్‌ను అనుమతించండి"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"సైజ్ మార్చండి"</string>
@@ -929,7 +930,7 @@
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"అవును"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"పిన్ అక్షరాలను లేదా చిహ్నాలను కలిగి ఉంది"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>ను వెరిఫై చేయండి"</string>
- <string name="controls_pin_wrong" msgid="6162694056042164211">"పిన్ తప్పు"</string>
+ <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN తప్పు"</string>
<string name="controls_pin_instructions" msgid="6363309783822475238">"పిన్‌ని ఎంటర్ చేయండి"</string>
<string name="controls_pin_instructions_retry" msgid="1566667581012131046">"మరొక పిన్‌ని ప్రయత్నించండి"</string>
<string name="controls_confirmation_message" msgid="7744104992609594859">"<xliff:g id="DEVICE">%s</xliff:g>కి సంబంధించి మార్పును నిర్ధారించండి"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>లో <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> రన్ అవుతోంది"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"ప్లే చేయండి"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"పాజ్ చేయండి"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"మునుపటి ట్రాక్"</string>
@@ -1076,7 +1078,7 @@
<string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# యాప్ యాక్టివ్‌గా ఉంది}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>
+ <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"మీరు ఈ యాప్‌లను ఉపయోగించపోయినా కూడా అవి యాక్టివ్‌గా ఉండి, రన్ అవుతూ ఉంటాయి. దీని వల్ల వాటి ఫంక్షనాలిటీ మెరుగవుతుంది. అయితే ఇది బ్యాటరీ లైఫ్‌ను కూడా ప్రభావితం చేయవచ్చు."</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ఆపివేయండి"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ఆపివేయబడింది"</string>
<string name="clipboard_edit_text_done" msgid="4551887727694022409">"పూర్తయింది"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant వింటోంది"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"నోట్‌టేకింగ్"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్‌పుట్‌ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 4d971dc8dc9e..ad1128b40320 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"แชร์"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"บันทึกการบันทึกหน้าจอแล้ว"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"แตะเพื่อดู"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"เกิดข้อผิดพลาดในการบันทึกหน้าจอ"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
<string name="accessibility_back" msgid="6530104400086152611">"กลับ"</string>
<string name="accessibility_home" msgid="5430449841237966217">"หน้าแรก"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ยืนยันแล้ว"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"ปลดล็อกด้วยใบหน้าแล้ว"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ขยายเป็นเต็มหน้าจอ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ขยายบางส่วนของหน้าจอ"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"เปิดการตั้งค่าการขยาย"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"ปิดการตั้งค่าการขยาย"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ลากที่มุมเพื่อปรับขนาด"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"อนุญาตการเลื่อนแบบทแยงมุม"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ปรับขนาด"</string>
@@ -906,12 +907,12 @@
<string name="accessibility_control_move" msgid="8980344493796647792">"ย้ายไปที่ตำแหน่ง <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"การควบคุม"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"เลือกระบบควบคุมอุปกรณ์ที่ต้องการให้เข้าถึงได้อย่างรวดเร็ว"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"แตะตัวควบคุมค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"นำตัวควบคุมทั้งหมดออกแล้ว"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"แตะระบบควบคุมค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"นำระบบควบคุมทั้งหมดออกแล้ว"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ยังไม่ได้บันทึกการเปลี่ยนแปลง"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"ดูแอปอื่นๆ"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"จัดเรียงใหม่"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"เพิ่มตัวควบคุม"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"เพิ่มระบบควบคุม"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"กลับไปที่การแก้ไข"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"โหลดตัวควบคุมไม่ได้ ตรวจสอบแอป <xliff:g id="APP">%s</xliff:g> ให้แน่ใจว่าการตั้งค่าของแอปไม่เปลี่ยนแปลง"</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"ตัวควบคุมที่เข้ากันได้ไม่พร้อมใช้งาน"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"กำลังเปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> จาก <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงาน"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"เล่น"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"หยุดชั่วคราว"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"แทร็กก่อนหน้า"</string>
@@ -970,7 +972,7 @@
<string name="controls_error_generic" msgid="352500456918362905">"โหลดสถานะไม่ได้"</string>
<string name="controls_error_failed" msgid="960228639198558525">"พบข้อผิดพลาด โปรดลองอีกครั้ง"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"เพิ่มตัวควบคุม"</string>
- <string name="controls_menu_edit" msgid="890623986951347062">"แก้ไขตัวควบคุม"</string>
+ <string name="controls_menu_edit" msgid="890623986951347062">"แก้ไขระบบควบคุม"</string>
<string name="controls_menu_add_another_app" msgid="8661172304650786705">"เพิ่มแอป"</string>
<string name="controls_menu_remove" msgid="3006525275966023468">"นำแอปออก"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"เพิ่มเอาต์พุต"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant กำลังฟังอยู่"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"การจดบันทึก"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 9d301c9ffd09..80fac072adfc 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ibahagi"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Na-save ang pag-record ng screen"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"I-tap para tingnan"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error sa pag-delete sa pag-record ng screen"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Nagka-error sa pag-save ng recording ng screen"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Bumalik"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Na-authenticate ang mukha"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Nakumpirma"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"I-tap ang Kumpirmahin para kumpletuhin"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para magpatuloy."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Na-unlock gamit ang mukha."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"I-magnify ang buong screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"I-magnify ang isang bahagi ng screen"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Buksan ang mga setting ng pag-magnify"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Isara ang mga setting ng pag-magnify"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"I-drag ang sulok para i-resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Payagan ang diagonal na pag-scroll"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"I-resize"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Nagpe-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sa <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"Tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"I-play"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"I-pause"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Nakaraang track"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Nakikinig ang Assistant"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Pagtatala"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 47c0b5ad7240..759dd292a6ee 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran kaydı kaydedildi"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran kaydı saklanırken hata oluştu"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ana sayfa"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yüz kimliği doğrulandı"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Onaylandı"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamak için Onayla\'ya dokunun"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Cihazın kilidini yüzünüzle açtınız."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
@@ -280,7 +280,7 @@
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Açılıyor…"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Veri Tasarrufu açık"</string>
<string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# cihaz}other{# cihaz}}"</string>
- <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fener"</string>
+ <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"El feneri"</string>
<string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera kullanımda"</string>
<string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil veri"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="6105969068871138427">"Veri kullanımı"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekran büyütme"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir parçasını büyütün"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Büyütme ayarlarını aç"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Büyütme ayarlarını kapat"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Yeniden boyutlandırmak için köşeyi sürükleyin"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Çapraz kaydırmaya izin ver"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Yeniden boyutlandır"</string>
@@ -911,7 +912,7 @@
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Değişiklikler kaydedilmedi"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Tüm uygulamaları göster"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Yeniden düzenle"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Kontrol ekle"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Denetim ekle"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Düzenlemeye dön"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontroller yüklenemedi. Uygulama ayarlarının değişmediğinden emin olmak için <xliff:g id="APP">%s</xliff:g> uygulamasını kontrol edin."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Uyumlu kontrol bulunamadı"</string>
@@ -922,7 +923,7 @@
<string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> tarafından önerildi"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Cihaz kilitlendi"</string>
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Cihazlar kilit ekranında gösterilip buradan kontrol edilsin mi?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kilit ekranına harici cihazlarınız için kontroller ekleyebilirsiniz.\n\nCihaz uygulamanız, bazı cihazları telefonunuzun veya tabletinizin kilidini açmadan kontrol etmenize izin verebilir.\n\nAyarlar\'da istediğiniz zaman değişiklik yapabilirsiniz."</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kilit ekranına harici cihazlarınız için denetimler ekleyebilirsiniz.\n\nCihaz uygulamanız, bazı cihazları telefonunuzun veya tabletinizin kilidini açmadan denetlemenize izin verebilir.\n\nAyarlar\'da istediğiniz zaman değişiklik yapabilirsiniz."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Cihazlar kilit ekranından kontrol edilsin mi?"</string>
<string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Bazı cihazları telefonunuzun veya tabletinizin kilidini açmadan kontrol edebilirsiniz.Hangi cihazların bu şekilde kontrol edilebileceğini cihaz uygulamanız belirler."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Hayır, teşekkürler"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısı çalıyor"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> çalışıyor"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Çal"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Duraklat"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Önceki parça"</string>
@@ -972,7 +974,7 @@
<string name="controls_menu_add" msgid="4447246119229920050">"Denetim ekle"</string>
<string name="controls_menu_edit" msgid="890623986951347062">"Denetimleri düzenle"</string>
<string name="controls_menu_add_another_app" msgid="8661172304650786705">"Uygulama ekle"</string>
- <string name="controls_menu_remove" msgid="3006525275966023468">"Uygulamayı kaldır"</string>
+ <string name="controls_menu_remove" msgid="3006525275966023468">"Uygulama kaldır"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"Çıkışlar ekleyin"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçildi"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistan dinliyor"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Not alma"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 780a357aa7ee..4424871ceafe 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Запис екрана збережено"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Не вдалося зберегти запис відео з екрана"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Головна"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Обличчя автентифіковано"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Розблоковано (фейс-контроль)."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейсконтроль). Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Збільшення всього екрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Збільшити частину екрана"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Відкрити налаштування збільшення"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Закрити налаштування збільшення"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Потягніть кут, щоб змінити розмір"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволити прокручування по діагоналі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змінити розмір"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Пісня \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, грає в додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Відтворити"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Призупинити"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Попередня композиція"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Асистент слухає"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}other{# сповіщення}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Створення нотаток"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 0fcc8628ce23..4438f1bb6e10 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"اشتراک کریں"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"اسکرین ریکارڈنگ محفوظ ہو گئی"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"دیکھنے کے لیے تھپتھپائیں"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"اسکرین ریکارڈنگ محفوظ کرنے میں خرابی"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
<string name="accessibility_back" msgid="6530104400086152611">"واپس جائیں"</string>
<string name="accessibility_home" msgid="5430449841237966217">"ہوم"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چہرے کی تصدیق ہو گئی"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تصدیق شدہ"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"چہرے سے غیر مقفل کیا گیا۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"فُل اسکرین کو بڑا کریں"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"اسکرین کا حصہ بڑا کریں"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"میگنیفکیشن کی ترتیبات کھولیں"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"میگنیفکیشن کی ترتیبات بند کریں"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"سائز تبدیل کرنے کے لیے کونے کو گھسیٹیں"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"وتری سکرولنگ کی اجازت دیں"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"سائز تبدیل کریں"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> چل رہی ہے"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"چلائیں"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"روکیں"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"پچھلا ٹریک"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"اسسٹنٹ سن رہی ہے"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"نوٹ لینا"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"نشریات"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> براڈکاسٹنگ روکیں؟"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"اپنے اسٹائلس کو چارجر منسلک کریں"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"اسٹائلس بیٹری کم ہے"</string>
<string name="video_camera" msgid="7654002575156149298">"ویڈیو کیمرا"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"ذاتی ایپ سے کال نہیں کر سکتے"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"آپ کی تنظیم آپ کو صرف ورک ایپس سے کالز کرنے کی اجازت دیتی ہے"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ورک فون ایپ انسٹال کریں"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"منسوخ کریں"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"مقفل اسکرین کو حسب ضرورت بنائیں"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"مقفل اسکرین کو حسب ضرورت بنانے کے لیے غیر مقفل کریں"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دستیاب نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 37f0ebbb99c9..4a24cbb51e52 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Ulashish"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran lavhasi saqlandi"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Koʻrish uchun bosing"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran yozuvi saqlanmadi"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Orqaga"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Uyga"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yuzingiz aniqlandi"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Yuz orqali ochilgan. Davom etish uchun ochish belgisini bosing."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Yuz bilan ochildi."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ekranni toʻliq kattalashtirish"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran qismini kattalashtirish"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Kattalashtirish sozlamalarini ochish"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Kattalashtirish sozlamalarini yopish"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Oʻlchamini oʻzgartirish uchun burchakni torting"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonal aylantirishga ruxsat berish"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Oʻlchamini oʻzgartirish"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ishlamoqda"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Ijro"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauza"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Avvalgi trek"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent tinglamoqda"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Eslatma yozish"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Signal uzatish"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index a053fdab5c34..f58f07b173ef 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Chia sẻ"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Đã lưu bản ghi màn hình"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Nhấn để xem"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Lỗi khi xóa bản ghi màn hình"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Có lỗi xảy ra khi lưu video ghi màn hình"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Quay lại"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Trang chủ"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Đã xác thực khuôn mặt"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ðã xác nhận"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Nhấn vào Xác nhận để hoàn tất"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để tiếp tục."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Đã mở khoá bằng khuôn mặt."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Phóng to toàn màn hình"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Phóng to một phần màn hình"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Mở chế độ cài đặt phóng to"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Đóng bảng cài đặt tính năng phóng to"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Kéo góc để thay đổi kích thước"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Cho phép cuộn chéo"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Đổi kích thước"</string>
@@ -906,12 +907,12 @@
<string name="accessibility_control_move" msgid="8980344493796647792">"Di chuyển tới vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="controls_favorite_default_title" msgid="967742178688938137">"Các tùy chọn điều khiển"</string>
<string name="controls_favorite_subtitle" msgid="5818709315630850796">"Chọn các chế độ điều khiển thiết bị để truy cập nhanh"</string>
- <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Giữ và kéo để sắp xếp lại các tuỳ chọn điều khiển"</string>
- <string name="controls_favorite_removed" msgid="5276978408529217272">"Đã xóa tất cả tùy chọn điều khiển"</string>
+ <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Giữ và kéo để sắp xếp lại các chế độ điều khiển"</string>
+ <string name="controls_favorite_removed" msgid="5276978408529217272">"Đã xóa tất cả chế độ điều khiển"</string>
<string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Chưa lưu các thay đổi"</string>
<string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Xem ứng dụng khác"</string>
<string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Sắp xếp lại"</string>
- <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Thêm tuỳ chọn điều khiển"</string>
+ <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Thêm chế độ điều khiển"</string>
<string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Quay lại chế độ chỉnh sửa"</string>
<string name="controls_favorite_load_error" msgid="5126216176144877419">"Không tải được các chức năng điều khiển. Hãy kiểm tra ứng dụng <xliff:g id="APP">%s</xliff:g> để đảm bảo rằng thông tin cài đặt của ứng dụng chưa thay đổi."</string>
<string name="controls_favorite_load_none" msgid="7687593026725357775">"Không có các chức năng điều khiển tương thích"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Đang phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Phát"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Tạm dừng"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Bản nhạc trước"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Trợ lý đang nghe bạn nói"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Ghi chú"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c9b48ca877bd..48f4f89601f3 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"已保存屏幕录制内容"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"点按即可查看"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"删除屏幕录制内容时出错"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"保存屏幕录制内容时出错"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"主屏幕"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔身份验证成功"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已确认"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"点按“确认”即可完成"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已通过面孔识别解锁。按下解锁图标即可继续。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"已用面孔解锁"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
@@ -720,7 +720,7 @@
<string name="left_icon" msgid="5036278531966897006">"向左图标"</string>
<string name="right_icon" msgid="1103955040645237425">"向右图标"</string>
<string name="drag_to_add_tiles" msgid="8933270127508303672">"按住并拖动即可添加功能块"</string>
- <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"按住并拖动即可重新排列功能块"</string>
+ <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"按住并拖动即可重新排列图块"</string>
<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>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整个屏幕"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分屏幕"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"打开放大功能设置"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"关闭放大设置"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖动一角即可调整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允许沿对角线滚动"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"调整大小"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正在运行"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"暂停"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"上一首"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google 助理正在聆听"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}other{# 条通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"记录"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index c387743f2a91..e1f591bd8b2a 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影內容"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"輕按即可查看"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除錄影畫面時發生錯誤"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影時發生錯誤"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"首頁"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔已經驗證"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已使用面孔解鎖。按解鎖圖示即可繼續。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"已使用面孔解鎖。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大成個畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分螢幕畫面"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"開啟放大設定"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"關閉放大設定"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖曳角落即可調整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許斜角捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在透過 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」執行中"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"暫停"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"上一首曲目"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"「Google 助理」正在聆聽"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"做筆記"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index f9c7d7df3106..dc0ac09450f7 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影檔"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"輕觸即可查看"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除螢幕畫面錄製內容時發生錯誤"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影內容時發生錯誤"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
<string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
<string name="accessibility_home" msgid="5430449841237966217">"主畫面"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔驗證成功"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認完畢"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕觸 [確認] 完成驗證設定"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"裝置已透過人臉解鎖,按下「解鎖」圖示即可繼續操作。"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"裝置已由人臉解鎖。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整個螢幕畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大局部螢幕畫面"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"開啟放大功能設定"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"關閉放大設定"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖曳角落即可調整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許沿對角線捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"系統正透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>,共 <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」執行中"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"暫停"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"上一首"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google 助理正在聆聽"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"做筆記"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string>
@@ -1142,15 +1147,11 @@
<string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"將觸控筆接上充電器"</string>
<string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電力不足"</string>
<string name="video_camera" msgid="7654002575156149298">"攝影機"</string>
- <!-- no translation found for call_from_work_profile_title (5418253516453177114) -->
- <skip />
- <!-- no translation found for call_from_work_profile_text (2856337395968118274) -->
- <skip />
+ <string name="call_from_work_profile_title" msgid="5418253516453177114">"無法透過個人應用程式撥號"</string>
+ <string name="call_from_work_profile_text" msgid="2856337395968118274">"貴機構僅允許透過工作應用程式撥打電話"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string>
- <!-- no translation found for install_dialer_on_work_profile_action (2014659711597862506) -->
- <skip />
- <!-- no translation found for call_from_work_profile_close (5830072964434474143) -->
- <skip />
+ <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"安裝工作用電話應用程式"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"取消"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"自訂螢幕鎖定畫面"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解鎖後即可自訂螢幕鎖定畫面"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連上 Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 998b3a328f16..9e3443708026 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_share_label" msgid="5025590804030086930">"Yabelana"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"Okokuqopha iskrini kulondoloziwe"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"Thepha ukuze ubuke"</string>
- <string name="screenrecord_delete_error" msgid="2870506119743013588">"Iphutha lokususa ukurekhoda isikrini"</string>
+ <string name="screenrecord_save_error" msgid="5862648532560118815">"Iphutha lokulondoloza okokuqopha iskrini"</string>
<string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
<string name="accessibility_back" msgid="6530104400086152611">"Emuva"</string>
<string name="accessibility_home" msgid="5430449841237966217">"Ekhaya"</string>
@@ -142,7 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ubuso bufakazelwe ubuqiniso"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kuqinisekisiwe"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="3783056044917913453">"Kuvulwe ngobuso."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
@@ -859,6 +859,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Khulisa isikrini esigcwele"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Khulisa ingxenye eyesikrini"</string>
<string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Vula amasethingi okukhuliswa"</string>
+ <string name="magnification_close_settings_click_label" msgid="4642477260651704517">"Vala amasethingi okukhuliswa"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Hudula ikhona ukuze usayize kabusha"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Vumela ukuskrola oku-diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Shintsha usayizi"</string>
@@ -943,6 +944,7 @@
<string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"I-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> idlala kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
<string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ku-<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+ <string name="controls_media_empty_title" msgid="8296102892421573325">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza"</string>
<string name="controls_media_button_play" msgid="2705068099607410633">"Dlala"</string>
<string name="controls_media_button_pause" msgid="8614887780950376258">"Misa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Ithrekhi yangaphambilini"</string>
@@ -1106,7 +1108,10 @@
<string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"I-Assistant ilalele"</string>
<string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</string>
<string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
- <string name="note_task_button_label" msgid="8718616095800343136">"Ukuthatha amanothi"</string>
+ <!-- no translation found for note_task_button_label (230135078402003532) -->
+ <skip />
+ <!-- no translation found for note_task_shortcut_long_label (7729325091147319409) -->
+ <skip />
<string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index bd86e51ccf8f..3a1d1a8cbf9d 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -216,6 +216,8 @@
<attr name="progress" format="integer" />
<attr name="iconStartContentDescription" format="reference" />
<attr name="iconEndContentDescription" format="reference" />
+ <attr name="tickMark" format="reference" />
+ <attr name="seekBarChangeMagnitude" format="integer" />
</declare-styleable>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8d3ba364da06..50d33c6a733b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -275,6 +275,9 @@
<!-- The padding at start and end of indication text shown on AOD -->
<dimen name="keyguard_indication_text_padding">16dp</dimen>
+ <!-- The min height on the indication text shown on AOD -->
+ <dimen name="keyguard_indication_text_min_height">48dp</dimen>
+
<!-- Shadows under the clock, date and other keyguard text fields -->
<dimen name="keyguard_shadow_radius">5</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index e5c946156e46..d651a2159721 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -206,5 +206,9 @@
<!-- keyboard backlight indicator-->
<item type="id" name="backlight_icon" />
-</resources>
+ <item type="id" name="keyguard_root_view" />
+ <item type="id" name="keyguard_indication_area" />
+ <item type="id" name="keyguard_indication_text" />
+ <item type="id" name="keyguard_indication_text_bottom" />
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e8b9f2a35659..ab789d90ebcf 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -613,8 +613,8 @@
<string name="quick_settings_bluetooth_secondary_label_headset">Headset</string>
<!-- QuickSettings: Bluetooth secondary label for an input/IO device being connected [CHAR LIMIT=20]-->
<string name="quick_settings_bluetooth_secondary_label_input">Input</string>
- <!-- QuickSettings: Bluetooth secondary label for a Hearing Aids device being connected [CHAR LIMIT=20]-->
- <string name="quick_settings_bluetooth_secondary_label_hearing_aids">Hearing Aids</string>
+ <!-- QuickSettings: Bluetooth secondary label for a Hearing aids device being connected [CHAR LIMIT=20]-->
+ <string name="quick_settings_bluetooth_secondary_label_hearing_aids">Hearing aids</string>
<!-- QuickSettings: Bluetooth secondary label shown when bluetooth is being enabled [CHAR LIMIT=NONE] -->
<string name="quick_settings_bluetooth_secondary_label_transient">Turning on&#8230;</string>
<!-- QuickSettings: Brightness [CHAR LIMIT=NONE] -->
@@ -2973,9 +2973,11 @@
<xliff:g id="weather_condition" example="Partly cloudy">%1$s</xliff:g>, <xliff:g id="temperature" example="7°C">%2$s</xliff:g>
</string>
- <!-- TODO(b/259369672): Replace with final resource. -->
<!-- [CHAR LIMIT=30] Label used to open Note Task -->
- <string name="note_task_button_label">Notetaking</string>
+ <string name="note_task_button_label">Note-taking</string>
+
+ <!-- [CHAR LIMIT=25] Long label used by Note Task Shortcut -->
+ <string name="note_task_shortcut_long_label">Note-taking, <xliff:g id="note_taking_app" example="Note-taking App">%1$s</xliff:g></string>
<!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting -->
<string name="broadcasting_description_is_broadcasting">Broadcasting</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index cee21353bd68..cb5342a0d66b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1183,12 +1183,6 @@
<style name="TextAppearance.InternetDialog.Secondary.Active"/>
- <style name="InternetDialog.Divider">
- <item name="android:background">?android:attr/textColorSecondary</item>
- </style>
-
- <style name="InternetDialog.Divider.Active"/>
-
<style name="FgsManagerDialogTitle">
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textStyle">bold</item>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 117cf78a4fe3..4b31498e659b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -48,7 +48,7 @@ interface ISystemUiProxy {
*
* Normal gesture: DOWN, MOVE/POINTER_DOWN/POINTER_UP)*, UP or CANCLE
*/
- oneway void onStatusBarMotionEvent(in MotionEvent event) = 9;
+ oneway void onStatusBarTouchEvent(in MotionEvent event) = 9;
/**
* Proxies the assistant gesture's progress started from navigation bar.
@@ -125,5 +125,15 @@ interface ISystemUiProxy {
*/
oneway void takeScreenshot(in ScreenshotRequest request) = 51;
- // Next id = 52
+ /**
+ * Dispatches trackpad status bar motion event to the notification shade. Currently these events
+ * are from the input monitor in {@link TouchInteractionService}. This is different from
+ * {@link #onStatusBarTouchEvent} above in that, this directly dispatches motion events to the
+ * notification shade, while {@link #onStatusBarTouchEvent} relies on setting the launcher
+ * window slippery to allow the frameworks to route those events after passing the initial
+ * threshold.
+ */
+ oneway void onStatusBarTrackpadEvent(in MotionEvent event) = 52;
+
+ // Next id = 53
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
index 9a0044761504..0ca2f7a36311 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
@@ -263,6 +263,8 @@ constructor(
(colors?.colorHints?.and(WallpaperColors.HINT_SUPPORTS_DARK_TEXT)) !=
WallpaperColors.HINT_SUPPORTS_DARK_TEXT
)
+ if (DEBUG)
+ Log.d(TAG, "onColorsChanged() | region darkness = $regionDarkness for region $area")
updateForegroundColor()
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt
new file mode 100644
index 000000000000..495d3a13d961
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.Executor
+
+/**
+ * [UnfoldTransitionProgressProvider] that emits transition progress only when unfolding but not
+ * when folding, so we can play the animation only one way but not the other way.
+ */
+class UnfoldOnlyProgressProvider(
+ foldProvider: FoldProvider,
+ @Main private val executor: Executor,
+ private val sourceProvider: UnfoldTransitionProgressProvider,
+ private val scopedProvider: ScopedUnfoldTransitionProgressProvider =
+ ScopedUnfoldTransitionProgressProvider(sourceProvider)
+) : UnfoldTransitionProgressProvider by scopedProvider {
+
+ private var isFolded = false
+
+ init {
+ foldProvider.registerCallback(FoldListener(), executor)
+ sourceProvider.addCallback(SourceTransitionListener())
+ }
+
+ private inner class SourceTransitionListener : TransitionProgressListener {
+ override fun onTransitionFinished() {
+ // Disable scoped progress provider after the first unfold animation, so fold animation
+ // will not be propagated. It will be re-enabled after folding so we can play
+ // the unfold animation again.
+ if (!isFolded) {
+ scopedProvider.setReadyToHandleTransition(false)
+ }
+ }
+ }
+
+ private inner class FoldListener : FoldCallback {
+ override fun onFoldUpdated(isFolded: Boolean) {
+ if (isFolded) {
+ scopedProvider.setReadyToHandleTransition(true)
+ }
+
+ this@UnfoldOnlyProgressProvider.isFolded = isFolded
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 8ea4c31a5ac9..84a2c25999a0 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -15,18 +15,18 @@
*/
package com.android.keyguard
-import android.app.WallpaperManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Resources
import android.text.format.DateFormat
-import android.util.TypedValue
import android.util.Log
+import android.util.TypedValue
import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.ViewTreeObserver
+import android.widget.FrameLayout
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -99,6 +99,28 @@ constructor(
if (!regionSamplingEnabled) {
updateColors()
+ } else {
+ clock?.let {
+ smallRegionSampler = createRegionSampler(
+ it.smallClock.view,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ isLockscreen = true,
+ ::updateColors
+ )?.apply { startRegionSampler() }
+
+ largeRegionSampler = createRegionSampler(
+ it.largeClock.view,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ isLockscreen = true,
+ ::updateColors
+ )?.apply { startRegionSampler() }
+
+ updateColors()
+ }
}
updateFontSizes()
updateTimeListeners()
@@ -110,8 +132,25 @@ constructor(
}
value.smallClock.view.addOnAttachStateChangeListener(
object : OnAttachStateChangeListener {
- override fun onViewAttachedToWindow(p0: View?) {
+ var pastVisibility: Int? = null
+ override fun onViewAttachedToWindow(view: View?) {
value.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
+ if (view != null) {
+ val smallClockFrame = view.parent as FrameLayout
+ pastVisibility = smallClockFrame.visibility
+ smallClockFrame.viewTreeObserver.addOnGlobalLayoutListener(
+ ViewTreeObserver.OnGlobalLayoutListener {
+ val currentVisibility = smallClockFrame.visibility
+ if (pastVisibility != currentVisibility) {
+ pastVisibility = currentVisibility
+ // when small clock visible, recalculate bounds and sample
+ if (currentVisibility == View.VISIBLE) {
+ smallRegionSampler?.stopRegionSampler()
+ smallRegionSampler?.startRegionSampler()
+ }
+ }
+ })
+ }
}
override fun onViewDetachedFromWindow(p0: View?) {
@@ -141,21 +180,19 @@ constructor(
private fun updateColors() {
- val wallpaperManager = WallpaperManager.getInstance(context)
if (regionSamplingEnabled) {
- regionSampler?.let { regionSampler ->
- clock?.let { clock ->
- if (regionSampler.sampledView == clock.smallClock.view) {
- smallClockIsDark = regionSampler.currentRegionDarkness().isDark
- clock.smallClock.events.onRegionDarknessChanged(smallClockIsDark)
- return@updateColors
- } else if (regionSampler.sampledView == clock.largeClock.view) {
- largeClockIsDark = regionSampler.currentRegionDarkness().isDark
- clock.largeClock.events.onRegionDarknessChanged(largeClockIsDark)
- return@updateColors
- }
+ clock?.let { clock ->
+ smallRegionSampler?.let {
+ smallClockIsDark = it.currentRegionDarkness().isDark
+ clock.smallClock.events.onRegionDarknessChanged(smallClockIsDark)
+ }
+
+ largeRegionSampler?.let {
+ largeClockIsDark = it.currentRegionDarkness().isDark
+ clock.largeClock.events.onRegionDarknessChanged(largeClockIsDark)
}
}
+ return
}
val isLightTheme = TypedValue()
@@ -168,23 +205,6 @@ constructor(
largeClock.events.onRegionDarknessChanged(largeClockIsDark)
}
}
-
- private fun updateRegionSampler(sampledRegion: View) {
- regionSampler?.stopRegionSampler()
- regionSampler =
- createRegionSampler(
- sampledRegion,
- mainExecutor,
- bgExecutor,
- regionSamplingEnabled,
- isLockscreen = true,
- ::updateColors
- )
- ?.apply { startRegionSampler() }
-
- updateColors()
- }
-
protected open fun createRegionSampler(
sampledView: View,
mainExecutor: Executor?,
@@ -202,7 +222,10 @@ constructor(
) { updateColors() }
}
- var regionSampler: RegionSampler? = null
+ var smallRegionSampler: RegionSampler? = null
+ private set
+ var largeRegionSampler: RegionSampler? = null
+ private set
var smallTimeListener: TimeListener? = null
var largeTimeListener: TimeListener? = null
val shouldTimeListenerRun: Boolean
@@ -319,7 +342,8 @@ constructor(
configurationController.removeCallback(configListener)
batteryController.removeCallback(batteryCallback)
keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
- regionSampler?.stopRegionSampler()
+ smallRegionSampler?.stopRegionSampler()
+ largeRegionSampler?.stopRegionSampler()
smallTimeListener?.stop()
largeTimeListener?.stop()
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 3defec72981f..25ad3af52d04 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -86,6 +86,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private int mKeyguardSmallClockTopMargin = 0;
private int mKeyguardLargeClockTopMargin = 0;
+ private int mKeyguardDateWeatherViewInvisibility = View.INVISIBLE;
private final ClockRegistry.ClockChangeListener mClockChangedListener;
private ViewGroup mStatusArea;
@@ -201,6 +202,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
mKeyguardLargeClockTopMargin =
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
+ mKeyguardDateWeatherViewInvisibility =
+ mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility);
if (mOnlyClock) {
View ksv = mView.findViewById(R.id.keyguard_slice_view);
@@ -335,7 +338,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
mKeyguardLargeClockTopMargin =
mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
+ mKeyguardDateWeatherViewInvisibility =
+ mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility);
mView.updateClockTargetRegions();
+ setDateWeatherVisibility();
}
@@ -489,8 +495,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private void setDateWeatherVisibility() {
if (mDateWeatherView != null) {
mUiExecutor.execute(() -> {
- mDateWeatherView.setVisibility(
- clockHasCustomWeatherDataDisplay() ? View.INVISIBLE : View.VISIBLE);
+ mDateWeatherView.setVisibility(clockHasCustomWeatherDataDisplay()
+ ? mKeyguardDateWeatherViewInvisibility
+ : View.VISIBLE);
});
}
}
@@ -524,9 +531,13 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
if (clock != null) {
clock.dump(pw);
}
- final RegionSampler regionSampler = mClockEventController.getRegionSampler();
- if (regionSampler != null) {
- regionSampler.dump(pw);
+ final RegionSampler smallRegionSampler = mClockEventController.getSmallRegionSampler();
+ if (smallRegionSampler != null) {
+ smallRegionSampler.dump(pw);
+ }
+ final RegionSampler largeRegionSampler = mClockEventController.getLargeRegionSampler();
+ if (largeRegionSampler != null) {
+ largeRegionSampler.dump(pw);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index afc25909ca91..99b5d52f8322 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -158,15 +158,18 @@ public class KeyguardPatternView extends KeyguardInputView
public void startAppearAnimation() {
enableClipping(false);
- setAlpha(1f);
+ setAlpha(0f);
setTranslationY(mAppearAnimationUtils.getStartTranslation());
AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
0, mAppearAnimationUtils.getInterpolator(),
getAnimationListener(InteractionJankMonitor.CUJ_LOCKSCREEN_PATTERN_APPEAR));
- mAppearAnimationUtils.startAnimation2d(
- mLockPatternView.getCellStates(),
- () -> enableClipping(true),
- this);
+ mLockPatternView.post(() -> {
+ setAlpha(1f);
+ mAppearAnimationUtils.startAnimation2d(
+ mLockPatternView.getCellStates(),
+ () -> enableClipping(true),
+ KeyguardPatternView.this);
+ });
if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt
new file mode 100644
index 000000000000..5c66b82d7c40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.constraintlayout.helper.widget.Flow
+import androidx.constraintlayout.widget.ConstraintLayout
+
+class KeyguardPinFlowView(context: Context, attrs: AttributeSet?) : Flow(context, attrs) {
+ // Overriding this so that visibilities of child views do not get updated.
+ override fun applyLayoutFeatures(container: ConstraintLayout?) {}
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 4b021716f506..4211f55787d9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -1226,15 +1226,16 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
constraintSet.constrainHeight(mViewFlipper.getId(), MATCH_CONSTRAINT);
constraintSet.applyTo(mView);
} else {
- int leftElement = leftAlign ? mViewFlipper.getId() : mUserSwitcherViewGroup.getId();
- int rightElement =
+ int startElement =
+ leftAlign ? mViewFlipper.getId() : mUserSwitcherViewGroup.getId();
+ int endElement =
leftAlign ? mUserSwitcherViewGroup.getId() : mViewFlipper.getId();
ConstraintSet constraintSet = new ConstraintSet();
- constraintSet.connect(leftElement, LEFT, PARENT_ID, LEFT);
- constraintSet.connect(leftElement, RIGHT, rightElement, LEFT);
- constraintSet.connect(rightElement, LEFT, leftElement, RIGHT);
- constraintSet.connect(rightElement, RIGHT, PARENT_ID, RIGHT);
+ constraintSet.connect(startElement, START, PARENT_ID, START);
+ constraintSet.connect(startElement, END, endElement, START);
+ constraintSet.connect(endElement, START, startElement, END);
+ constraintSet.connect(endElement, END, PARENT_ID, END);
constraintSet.connect(mUserSwitcherViewGroup.getId(), TOP, PARENT_ID, TOP);
constraintSet.connect(mUserSwitcherViewGroup.getId(), BOTTOM, PARENT_ID, BOTTOM);
constraintSet.connect(mViewFlipper.getId(), TOP, PARENT_ID, TOP);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 1db0ab65e44f..835cc13bebb1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -46,7 +46,6 @@ import com.android.keyguard.KeyguardClockSwitch.ClockSize;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.R;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ClockController;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -363,7 +362,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
boolean customClockAnimation = clock != null
&& clock.getLargeClock().getConfig().getHasCustomPositionUpdatedAnimation();
- if (mFeatureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION) && customClockAnimation) {
+ if (customClockAnimation) {
// Find the clock, so we can exclude it from this transition.
FrameLayout clockContainerView = mView.findViewById(R.id.lockscreen_clock_view_large);
@@ -400,8 +399,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@VisibleForTesting
static class SplitShadeTransitionAdapter extends Transition {
private static final String PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft";
+ private static final String PROP_BOUNDS_RIGHT = "splitShadeTransitionAdapter:boundsRight";
private static final String PROP_X_IN_WINDOW = "splitShadeTransitionAdapter:xInWindow";
- private static final String[] TRANSITION_PROPERTIES = { PROP_BOUNDS_LEFT, PROP_X_IN_WINDOW};
+ private static final String[] TRANSITION_PROPERTIES = {
+ PROP_BOUNDS_LEFT, PROP_BOUNDS_RIGHT, PROP_X_IN_WINDOW};
private final KeyguardClockSwitchController mController;
@@ -412,6 +413,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private void captureValues(TransitionValues transitionValues) {
transitionValues.values.put(PROP_BOUNDS_LEFT, transitionValues.view.getLeft());
+ transitionValues.values.put(PROP_BOUNDS_RIGHT, transitionValues.view.getRight());
int[] locationInWindowTmp = new int[2];
transitionValues.view.getLocationInWindow(locationInWindowTmp);
transitionValues.values.put(PROP_X_IN_WINDOW, locationInWindowTmp[0]);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 0f0ebed01e82..894158c1b092 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -246,6 +246,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private static final int MSG_TIME_FORMAT_UPDATE = 344;
private static final int MSG_REQUIRE_NFC_UNLOCK = 345;
private static final int MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED = 346;
+ private static final int MSG_SERVICE_PROVIDERS_UPDATED = 347;
/** Biometric authentication state: Not listening. */
private static final int BIOMETRIC_STATE_STOPPED = 0;
@@ -1818,6 +1819,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
} else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
+ } else if (TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED.equals(action)) {
+ mHandler.obtainMessage(MSG_SERVICE_PROVIDERS_UPDATED, intent).sendToTarget();
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
} else if (Intent.ACTION_SERVICE_STATE.equals(action)) {
@@ -2387,6 +2390,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
case MSG_SERVICE_STATE_CHANGE:
handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
break;
+ case MSG_SERVICE_PROVIDERS_UPDATED:
+ handleServiceProvidersUpdated((Intent) msg.obj);
+ break;
case MSG_SCREEN_TURNED_OFF:
Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_OFF");
handleScreenTurnedOff();
@@ -2457,6 +2463,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
filter.addAction(Intent.ACTION_SERVICE_STATE);
filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+ filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
mBroadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter, mHandler);
@@ -3712,6 +3719,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
+ * Handle {@link #MSG_SERVICE_PROVIDERS_UPDATED}
+ */
+ private void handleServiceProvidersUpdated(Intent intent) {
+ mLogger.logServiceProvidersUpdated(intent);
+ callbacksRefreshCarrierInfo();
+ }
+
+ /**
* Whether the keyguard is showing and not occluded.
*/
public boolean isKeyguardVisible() {
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index 2d0bf9cc2aba..d2b10d687f04 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -63,7 +63,11 @@ public abstract class ClockRegistryModule {
bgDispatcher,
featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
/* handleAllUsers= */ true,
- new DefaultClockProvider(context, layoutInflater, resources),
+ new DefaultClockProvider(
+ context,
+ layoutInflater,
+ resources,
+ featureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION)),
context.getString(R.string.lockscreen_clock_id_fallback),
logBuffer,
/* keepAllLoaded = */ false,
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 17cc23632d94..4923ab0fab18 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -16,11 +16,15 @@
package com.android.keyguard.logging
+import android.content.Intent
import android.hardware.biometrics.BiometricConstants.LockoutMode
import android.os.PowerManager
import android.os.PowerManager.WakeReason
import android.telephony.ServiceState
import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import android.telephony.TelephonyManager
import com.android.keyguard.ActiveUnlockConfig
import com.android.keyguard.FaceAuthUiEvent
import com.android.keyguard.KeyguardListenModel
@@ -363,6 +367,21 @@ constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
)
}
+ fun logServiceProvidersUpdated(intent: Intent) {
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID)
+ str1 = intent.getStringExtra(TelephonyManager.EXTRA_SPN)
+ str2 = intent.getStringExtra(TelephonyManager.EXTRA_PLMN)
+ },
+ {
+ "action SERVICE_PROVIDERS_UPDATED subId=$int1 spn=$str1 plmn=$str2"
+ }
+ )
+ }
+
fun logSimState(subId: Int, slotId: Int, state: Int) {
logBuffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 99d46629ad7a..c30a2146436c 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -20,6 +20,7 @@ import static androidx.dynamicanimation.animation.DynamicAnimation.TRANSLATION_X
import static androidx.dynamicanimation.animation.FloatPropertyCompat.createFloatPropertyCompat;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
+import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -54,9 +55,10 @@ import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.PhysicsAnimator;
import com.android.wm.shell.animation.PhysicsAnimator.SpringConfig;
+import java.io.PrintWriter;
import java.util.function.Consumer;
-public class SwipeHelper implements Gefingerpoken {
+public class SwipeHelper implements Gefingerpoken, Dumpable {
static final String TAG = "com.android.systemui.SwipeHelper";
private static final boolean DEBUG_INVALIDATE = false;
private static final boolean CONSTRAIN_SWIPE = true;
@@ -844,6 +846,31 @@ public class SwipeHelper implements Gefingerpoken {
return false;
}
+ @Override
+ public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.append("mTouchedView=").print(mTouchedView);
+ if (mTouchedView instanceof ExpandableNotificationRow) {
+ pw.append(" key=").println(logKey((ExpandableNotificationRow) mTouchedView));
+ } else {
+ pw.println();
+ }
+ pw.append("mIsSwiping=").println(mIsSwiping);
+ pw.append("mSnappingChild=").println(mSnappingChild);
+ pw.append("mLongPressSent=").println(mLongPressSent);
+ pw.append("mInitialTouchPos=").println(mInitialTouchPos);
+ pw.append("mTranslation=").println(mTranslation);
+ pw.append("mCanCurrViewBeDimissed=").println(mCanCurrViewBeDimissed);
+ pw.append("mMenuRowIntercepting=").println(mMenuRowIntercepting);
+ pw.append("mDisableHwLayers=").println(mDisableHwLayers);
+ pw.append("mDismissPendingMap: ").println(mDismissPendingMap.size());
+ if (!mDismissPendingMap.isEmpty()) {
+ mDismissPendingMap.forEach((view, animator) -> {
+ pw.append(" ").print(view);
+ pw.append(": ").println(animator);
+ });
+ }
+ }
+
public interface Callback {
View getChildAtPosition(MotionEvent ev);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 7c765889a381..e7eab7e462e1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -76,6 +76,7 @@ import android.widget.ImageView;
import androidx.core.math.MathUtils;
+import com.android.internal.accessibility.common.MagnificationConstants;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.R;
@@ -101,7 +102,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
// Delay to avoid updating state description too frequently.
private static final int UPDATE_STATE_DESCRIPTION_DELAY_MS = 100;
// It should be consistent with the value defined in WindowMagnificationGestureHandler.
- private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(1.0f, 8.0f);
+ private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(
+ MagnificationConstants.SCALE_MIN_VALUE,
+ MagnificationConstants.SCALE_MAX_VALUE);
private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
private static final float ANIMATION_BOUNCE_EFFECT_SCALE = 1.05f;
private final SparseArray<Float> mMagnificationSizeScaleOptions = new SparseArray<>();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index d0ff9f82db92..b086912bd904 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -22,6 +22,9 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MAX_VALUE;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MIN_VALUE;
+
import android.annotation.IntDef;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -79,14 +82,16 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
private final Runnable mWindowInsetChangeRunnable;
private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
- private final LayoutParams mParams;
+ @VisibleForTesting
+ final LayoutParams mParams;
@VisibleForTesting
final Rect mDraggableWindowBounds = new Rect();
private boolean mIsVisible = false;
private final MagnificationGestureDetector mGestureDetector;
private boolean mSingleTapDetected = false;
- private SeekBarWithIconButtonsView mZoomSeekbar;
+ @VisibleForTesting
+ SeekBarWithIconButtonsView mZoomSeekbar;
private LinearLayout mAllowDiagonalScrollingView;
private TextView mAllowDiagonalScrollingTitle;
private Switch mAllowDiagonalScrollingSwitch;
@@ -101,11 +106,15 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
private ImageButton mFullScreenButton;
private int mLastSelectedButtonIndex = MagnificationSize.NONE;
private boolean mAllowDiagonalScrolling = false;
- private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
- private static final float A11Y_SCALE_MIN_VALUE = 1.0f;
+ /**
+ * Amount by which magnification scale changes compared to seekbar in settings.
+ * magnitude = 10 means, for every 1 scale increase, 10 progress increase in seekbar.
+ */
+ private int mSeekBarMagnitude;
private WindowMagnificationSettingsCallback mCallback;
private ContentObserver mMagnificationCapabilityObserver;
+ private ContentObserver mMagnificationScaleObserver;
@Retention(RetentionPolicy.SOURCE)
@IntDef({
@@ -155,18 +164,26 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
});
}
};
+ mMagnificationScaleObserver = new ContentObserver(
+ mContext.getMainThreadHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ setScaleSeekbar(getMagnificationScale());
+ }
+ };
}
private class ZoomSeekbarChangeListener implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- float scale = progress * A11Y_CHANGE_SCALE_DIFFERENCE + A11Y_SCALE_MIN_VALUE;
+ float scale = (progress / (float) mSeekBarMagnitude) + SCALE_MIN_VALUE;
// Update persisted scale only when scale >= PERSISTED_SCALE_MIN_VALUE const.
// We assume if the scale is lower than the PERSISTED_SCALE_MIN_VALUE, there will be
// no obvious magnification effect.
if (scale >= MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) {
- Settings.Secure.putFloatForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale,
+ mSecureSettings.putFloatForUser(
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ scale,
UserHandle.USER_CURRENT);
}
mCallback.onMagnifierScale(scale);
@@ -300,6 +317,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
// Unregister observer before removing view
mSecureSettings.unregisterContentObserver(mMagnificationCapabilityObserver);
+ mSecureSettings.unregisterContentObserver(mMagnificationScaleObserver);
mWindowManager.removeView(mSettingView);
mIsVisible = false;
if (resetPosition) {
@@ -328,7 +346,13 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
}
public void setScaleSeekbar(float scale) {
- setSeekbarProgress(scale);
+ int index = (int) ((scale - SCALE_MIN_VALUE) * mSeekBarMagnitude);
+ if (index < 0) {
+ index = 0;
+ } else if (index > mZoomSeekbar.getMax()) {
+ index = mZoomSeekbar.getMax();
+ }
+ mZoomSeekbar.setProgress(index);
}
private void transitToMagnificationMode(int mode) {
@@ -345,6 +369,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
private void showSettingPanel(boolean resetPosition) {
if (!mIsVisible) {
updateUIControlsIfNeeded();
+ setScaleSeekbar(getMagnificationScale());
if (resetPosition) {
mDraggableWindowBounds.set(getDraggableWindowBounds());
mParams.x = mDraggableWindowBounds.right;
@@ -357,6 +382,10 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
mMagnificationCapabilityObserver,
UserHandle.USER_CURRENT);
+ mSecureSettings.registerContentObserverForUser(
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ mMagnificationScaleObserver,
+ UserHandle.USER_CURRENT);
// Exclude magnification switch button from system gesture area.
setSystemGestureExclusion();
@@ -389,9 +418,15 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
UserHandle.USER_CURRENT);
}
+ private float getMagnificationScale() {
+ return mSecureSettings.getFloatForUser(
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ SCALE_MIN_VALUE,
+ UserHandle.USER_CURRENT);
+ }
+
private void updateUIControlsIfNeeded() {
int capability = getMagnificationCapability();
-
int selectedButtonIndex = mLastSelectedButtonIndex;
switch (capability) {
case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
@@ -452,14 +487,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
}
};
- private void setSeekbarProgress(float scale) {
- int index = (int) ((scale - A11Y_SCALE_MIN_VALUE) / A11Y_CHANGE_SCALE_DIFFERENCE);
- if (index < 0) {
- index = 0;
- }
- mZoomSeekbar.setProgress(index);
- }
-
void inflateView() {
mSettingView = (LinearLayout) View.inflate(mContext,
R.layout.window_magnification_settings_view, null);
@@ -481,10 +508,13 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
mSettingView.findViewById(R.id.magnifier_horizontal_lock_title);
mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
+ mZoomSeekbar.setMax((int) (mZoomSeekbar.getChangeMagnitude()
+ * (SCALE_MAX_VALUE - SCALE_MIN_VALUE)));
+ mSeekBarMagnitude = mZoomSeekbar.getChangeMagnitude();
float scale = mSecureSettings.getFloatForUser(
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0,
UserHandle.USER_CURRENT);
- setSeekbarProgress(scale);
+ setScaleSeekbar(scale);
mZoomSeekbar.setOnSeekBarChangeListener(new ZoomSeekbarChangeListener());
mAllowDiagonalScrollingView =
@@ -529,7 +559,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
// CONFIG_FONT_SCALE: font size change
// CONFIG_LOCALE: language change
// CONFIG_DENSITY: display size change
-
mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
boolean showSettingPanelAfterConfigChange = mIsVisible;
@@ -541,16 +570,13 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
return;
}
- if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
- final Rect previousDraggableBounds = new Rect(mDraggableWindowBounds);
+ if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0
+ || (configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) {
mDraggableWindowBounds.set(getDraggableWindowBounds());
- // Keep the Y position with the same height ratio before the window bounds and
- // draggable bounds are changed.
- final float windowHeightFraction = (float) (mParams.y - previousDraggableBounds.top)
- / previousDraggableBounds.height();
- mParams.y = (int) (windowHeightFraction * mDraggableWindowBounds.height())
- + mDraggableWindowBounds.top;
- return;
+ // reset the panel position to the right-bottom corner
+ mParams.x = mDraggableWindowBounds.right;
+ mParams.y = mDraggableWindowBounds.bottom;
+ updateButtonViewLayoutIfNeeded();
}
}
@@ -562,7 +588,8 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
mDraggableWindowBounds.set(newBounds);
}
- private void updateButtonViewLayoutIfNeeded() {
+ @VisibleForTesting
+ void updateButtonViewLayoutIfNeeded() {
if (mIsVisible) {
mParams.x = MathUtils.constrain(mParams.x, mDraggableWindowBounds.left,
mDraggableWindowBounds.right);
@@ -603,7 +630,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
@VisibleForTesting
void setDiagonalScrolling(boolean enabled) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ mSecureSettings.putIntForUser(
Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING, enabled ? 1 : 0,
UserHandle.USER_CURRENT);
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index c684dc54c6fd..c4ebee2a9197 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -77,7 +77,7 @@ class AuthenticationRepositoryImpl @Inject constructor() : AuthenticationReposit
override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
private val _authenticationMethod =
- MutableStateFlow<AuthenticationMethodModel>(AuthenticationMethodModel.PIN(1234))
+ MutableStateFlow<AuthenticationMethodModel>(AuthenticationMethodModel.Pin(1234))
override val authenticationMethod: StateFlow<AuthenticationMethodModel> =
_authenticationMethod.asStateFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 3984627a181d..dd9dcbedd6fc 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.authentication.domain.interactor
+import android.app.admin.DevicePolicyManager
import com.android.systemui.authentication.data.repository.AuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.dagger.SysUISingleton
@@ -129,7 +130,7 @@ constructor(
fun authenticate(input: List<Any>): Boolean {
val isSuccessful =
when (val authMethod = this.authenticationMethod.value) {
- is AuthenticationMethodModel.PIN -> input.asCode() == authMethod.code
+ is AuthenticationMethodModel.Pin -> input.asCode() == authMethod.code
is AuthenticationMethodModel.Password -> input.asPassword() == authMethod.password
is AuthenticationMethodModel.Pattern -> input.asPattern() == authMethod.coordinates
else -> true
@@ -177,15 +178,21 @@ constructor(
/**
* Returns a PIN code from the given list. It's assumed the given list elements are all
- * [Int].
+ * [Int] in the range [0-9].
*/
- private fun List<Any>.asCode(): Int? {
- if (isEmpty()) {
+ private fun List<Any>.asCode(): Long? {
+ if (isEmpty() || size > DevicePolicyManager.MAX_PASSWORD_LENGTH) {
return null
}
- var code = 0
- map { it as Int }.forEach { integer -> code = code * 10 + integer }
+ var code = 0L
+ map {
+ require(it is Int && it in 0..9) {
+ "Pin is required to be Int in range [0..9], but got $it"
+ }
+ it
+ }
+ .forEach { integer -> code = code * 10 + integer }
return code
}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
index 6f008c3017b9..e4fbf9af35ea 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
@@ -32,7 +32,13 @@ sealed class AuthenticationMethodModel(
/** The most basic authentication method. The lock screen can be swiped away when displayed. */
object Swipe : AuthenticationMethodModel(isSecure = false)
- data class PIN(val code: Int) : AuthenticationMethodModel(isSecure = true)
+ /**
+ * Authentication method using a PIN.
+ *
+ * In practice, a pin is restricted to 16 decimal digits , see
+ * [android.app.admin.DevicePolicyManager.MAX_PASSWORD_LENGTH]
+ */
+ data class Pin(val code: Long) : AuthenticationMethodModel(isSecure = true)
data class Password(val password: String) : AuthenticationMethodModel(isSecure = true)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
index 682888fc39b5..95610aec3562 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
@@ -21,6 +21,7 @@ import android.content.Context
import com.airbnb.lottie.LottieAnimationView
import com.android.systemui.R
import com.android.systemui.biometrics.AuthBiometricView.BiometricState
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATED
import com.android.systemui.biometrics.AuthBiometricView.STATE_ERROR
import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
@@ -47,13 +48,16 @@ open class AuthBiometricFingerprintAndFaceIconController(
@BiometricState oldState: Int,
@BiometricState newState: Int
): Int? = when (newState) {
+ STATE_AUTHENTICATED -> {
+ if (oldState == STATE_PENDING_CONFIRMATION) {
+ R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie
+ } else {
+ super.getAnimationForTransition(oldState, newState)
+ }
+ }
STATE_PENDING_CONFIRMATION -> {
if (oldState == STATE_ERROR || oldState == STATE_HELP) {
R.raw.fingerprint_dialogue_error_to_unlock_lottie
- } else if (oldState == STATE_PENDING_CONFIRMATION) {
- // TODO(jbolinger): missing asset for this transition
- // (unlocked icon to success checkmark)
- R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie
} else {
R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index f04fdfff67f1..9807b9e6f1b3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -122,7 +122,9 @@ open class AuthBiometricFingerprintIconController(
if (shouldAnimateIconViewForTransition(lastState, newState)) {
iconView.playAnimation()
}
- LottieColorUtils.applyDynamicColors(context, iconView)
+ if (isSideFps) {
+ LottieColorUtils.applyDynamicColors(context, iconView)
+ }
}
override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index fb160f2a2f00..69ce78ce30a8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -109,6 +109,7 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
int ACTION_ERROR = 5;
int ACTION_USE_DEVICE_CREDENTIAL = 6;
int ACTION_START_DELAYED_FINGERPRINT_SENSOR = 7;
+ int ACTION_AUTHENTICATED_AND_CONFIRMED = 8;
/**
* When an action has occurred. The caller will only invoke this when the callback should
@@ -509,7 +510,8 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
}
public void updateState(@BiometricState int newState) {
- Log.v(TAG, "newState: " + newState);
+ Log.d(TAG, "newState: " + newState);
+
mIconController.updateState(mState, newState);
switch (newState) {
@@ -533,8 +535,14 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
}
announceForAccessibility(getResources()
.getString(R.string.biometric_dialog_authenticated));
- mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED),
- getDelayAfterAuthenticatedDurationMs());
+ if (mState == STATE_PENDING_CONFIRMATION) {
+ mHandler.postDelayed(() -> mCallback.onAction(
+ Callback.ACTION_AUTHENTICATED_AND_CONFIRMED),
+ getDelayAfterAuthenticatedDurationMs());
+ } else {
+ mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED),
+ getDelayAfterAuthenticatedDurationMs());
+ }
break;
case STATE_PENDING_CONFIRMATION:
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 49ac26411d3e..43a3b9958ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -213,6 +213,9 @@ public class AuthContainerView extends LinearLayout
case AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR:
mConfig.mCallback.onStartFingerprintNow(getRequestId());
break;
+ case AuthBiometricView.Callback.ACTION_AUTHENTICATED_AND_CONFIRMED:
+ animateAway(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE);
+ break;
default:
Log.e(TAG, "Unhandled action: " + action);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 07825377440b..baaa96efb5f0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -15,8 +15,6 @@
*/
package com.android.systemui.biometrics
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
import android.app.ActivityTaskManager
import android.content.Context
import android.content.res.Configuration
@@ -43,7 +41,6 @@ import android.view.Surface
import android.view.View
import android.view.View.AccessibilityDelegate
import android.view.ViewPropertyAnimator
-import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
@@ -61,7 +58,6 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
-import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.traceSection
import java.io.PrintWriter
@@ -83,7 +79,6 @@ constructor(
fingerprintManager: FingerprintManager?,
private val windowManager: WindowManager,
private val activityTaskManager: ActivityTaskManager,
- overviewProxyService: OverviewProxyService,
displayManager: DisplayManager,
private val displayStateInteractor: DisplayStateInteractor,
@Main private val mainExecutor: DelayableExecutor,
@@ -112,19 +107,6 @@ constructor(
@VisibleForTesting val orientationListener = orientationReasonListener.orientationListener
- @VisibleForTesting
- val overviewProxyListener =
- object : OverviewProxyService.OverviewProxyListener {
- override fun onTaskbarStatusUpdated(visible: Boolean, stashed: Boolean) {
- overlayView?.let { view ->
- handler.postDelayed({ updateOverlayVisibility(view) }, 500)
- }
- }
- }
-
- private val animationDuration =
- context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
-
private val isReverseDefaultRotation =
context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)
@@ -142,7 +124,6 @@ constructor(
field = value
field?.let { newView ->
windowManager.addView(newView, overlayViewParams)
- updateOverlayVisibility(newView)
orientationListener.enable()
}
}
@@ -152,7 +133,7 @@ constructor(
WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
PixelFormat.TRANSLUCENT
)
@@ -181,7 +162,6 @@ constructor(
override fun hide(sensorId: Int) = hide(SideFpsUiRequestSource.AUTO_SHOW)
}
)
- overviewProxyService.addCallback(overviewProxyListener)
listenForAlternateBouncerVisibility()
dumpManager.registerDumpable(this)
@@ -340,45 +320,6 @@ constructor(
windowManager.updateViewLayout(overlayView, overlayViewParams)
}
- private fun updateOverlayVisibility(view: View) {
- if (view != overlayView) {
- return
- }
- // hide after a few seconds if the sensor is oriented down and there are
- // large overlapping system bars
- var rotation = context.display?.rotation
-
- if (rotation != null) {
- rotation = getRotationFromDefault(rotation)
- }
-
- if (
- windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
- ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) ||
- (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))
- ) {
- overlayHideAnimator =
- view
- .animate()
- .alpha(0f)
- .setStartDelay(3_000)
- .setDuration(animationDuration)
- .setListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- view.visibility = View.GONE
- overlayHideAnimator = null
- }
- }
- )
- } else {
- overlayHideAnimator?.cancel()
- overlayHideAnimator = null
- view.alpha = 1f
- view.visibility = View.VISIBLE
- }
- }
-
private fun getRotationFromDefault(rotation: Int): Int =
if (isReverseDefaultRotation) (rotation + 1) % 4 else rotation
}
@@ -426,9 +367,6 @@ private fun SensorLocationInternal.isYAligned(): Boolean = sensorLocationY != 0
private fun Display.isNaturalOrientation(): Boolean =
rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
-private fun WindowInsets.hasBigNavigationBar(): Boolean =
- getInsets(WindowInsets.Type.navigationBars()).bottom >= 70
-
private fun LottieAnimationView.addOverlayDynamicColor(
context: Context,
@BiometricOverlayConstants.ShowReason reason: Int
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index e462e2f5b7d8..a24a421ff2e1 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -148,12 +148,17 @@ constructor(
*
* If the input is correct, the device will be unlocked and the lock screen and bouncer will be
* dismissed and hidden.
+ *
+ * @param input The input from the user to try to authenticate with. This can be a list of
+ * different things, based on the current authentication method.
+ * @return `true` if the authentication succeeded and the device is now unlocked; `false`
+ * otherwise.
*/
fun authenticate(
input: List<Any>,
- ) {
+ ): Boolean {
if (repository.throttling.value != null) {
- return
+ return false
}
val isAuthenticated = authenticationInteractor.authenticate(input)
@@ -186,11 +191,13 @@ constructor(
}
else -> repository.setMessage(errorMessage(authenticationMethod.value))
}
+
+ return isAuthenticated
}
private fun promptMessage(authMethod: AuthenticationMethodModel): String {
return when (authMethod) {
- is AuthenticationMethodModel.PIN ->
+ is AuthenticationMethodModel.Pin ->
applicationContext.getString(R.string.keyguard_enter_your_pin)
is AuthenticationMethodModel.Password ->
applicationContext.getString(R.string.keyguard_enter_your_password)
@@ -202,7 +209,7 @@ constructor(
private fun errorMessage(authMethod: AuthenticationMethodModel): String {
return when (authMethod) {
- is AuthenticationMethodModel.PIN -> applicationContext.getString(R.string.kg_wrong_pin)
+ is AuthenticationMethodModel.Pin -> applicationContext.getString(R.string.kg_wrong_pin)
is AuthenticationMethodModel.Password ->
applicationContext.getString(R.string.kg_wrong_password)
is AuthenticationMethodModel.Pattern ->
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
index 774a5593530c..d95b70c85fe0 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -16,14 +16,37 @@
package com.android.systemui.bouncer.ui.viewmodel
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
-sealed interface AuthMethodBouncerViewModel {
+sealed class AuthMethodBouncerViewModel(
/**
* Whether user input is enabled.
*
* If `false`, user input should be completely ignored in the UI as the user is "locked out" of
* being able to attempt to unlock the device.
*/
- val isInputEnabled: StateFlow<Boolean>
+ val isInputEnabled: StateFlow<Boolean>,
+) {
+
+ private val _animateFailure = MutableStateFlow(false)
+ /**
+ * Whether a failure animation should be shown. Once consumed, the UI must call
+ * [onFailureAnimationShown] to consume this state.
+ */
+ val animateFailure: StateFlow<Boolean> = _animateFailure.asStateFlow()
+
+ /**
+ * Notifies that the failure animation has been shown. This should be called to consume a `true`
+ * value in [animateFailure].
+ */
+ fun onFailureAnimationShown() {
+ _animateFailure.value = false
+ }
+
+ /** Ask the UI to show the failure animation. */
+ protected fun showFailureAnimation() {
+ _animateFailure.value = true
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index 02991bd47c6e..527fe6ec847d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -20,6 +20,7 @@ import android.content.Context
import com.android.systemui.R
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
import com.android.systemui.dagger.qualifiers.Application
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -29,6 +30,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -45,21 +47,6 @@ constructor(
) {
private val interactor: BouncerInteractor = interactorFactory.create(containerName)
- /**
- * Whether updates to the message should be cross-animated from one message to another.
- *
- * If `false`, no animation should be applied, the message text should just be replaced
- * instantly.
- */
- val isMessageUpdateAnimationsEnabled: StateFlow<Boolean> =
- interactor.throttling
- .map { it == null }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = interactor.throttling.value == null,
- )
-
private val isInputEnabled: StateFlow<Boolean> =
interactor.throttling
.map { it == null }
@@ -104,13 +91,21 @@ constructor(
)
/** The user-facing message to show in the bouncer. */
- val message: StateFlow<String> =
- interactor.message
- .map { it ?: "" }
+ val message: StateFlow<MessageViewModel> =
+ combine(
+ interactor.message,
+ interactor.throttling,
+ ) { message, throttling ->
+ toMessageViewModel(message, throttling)
+ }
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = interactor.message.value ?: "",
+ initialValue =
+ toMessageViewModel(
+ message = interactor.message.value,
+ throttling = interactor.throttling.value,
+ ),
)
private val _throttlingDialogMessage = MutableStateFlow<String?>(null)
@@ -131,7 +126,7 @@ constructor(
.map { model ->
model?.let {
when (interactor.authenticationMethod.value) {
- is AuthenticationMethodModel.PIN ->
+ is AuthenticationMethodModel.Pin ->
R.string.kg_too_many_failed_pin_attempts_dialog_message
is AuthenticationMethodModel.Password ->
R.string.kg_too_many_failed_password_attempts_dialog_message
@@ -170,13 +165,35 @@ constructor(
authMethod: AuthenticationMethodModel,
): AuthMethodBouncerViewModel? {
return when (authMethod) {
- is AuthenticationMethodModel.PIN -> pin
+ is AuthenticationMethodModel.Pin -> pin
is AuthenticationMethodModel.Password -> password
is AuthenticationMethodModel.Pattern -> pattern
else -> null
}
}
+ private fun toMessageViewModel(
+ message: String?,
+ throttling: AuthenticationThrottledModel?,
+ ): MessageViewModel {
+ return MessageViewModel(
+ text = message ?: "",
+ isUpdateAnimated = throttling == null,
+ )
+ }
+
+ data class MessageViewModel(
+ val text: String,
+
+ /**
+ * Whether updates to the message should be cross-animated from one message to another.
+ *
+ * If `false`, no animation should be applied, the message text should just be replaced
+ * instantly.
+ */
+ val isUpdateAnimated: Boolean,
+ )
+
@AssistedFactory
interface Factory {
fun create(
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index c38fcaa3b657..55929b566cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -24,8 +24,11 @@ import kotlinx.coroutines.flow.asStateFlow
/** Holds UI state and handles user input for the password bouncer UI. */
class PasswordBouncerViewModel(
private val interactor: BouncerInteractor,
- override val isInputEnabled: StateFlow<Boolean>,
-) : AuthMethodBouncerViewModel {
+ isInputEnabled: StateFlow<Boolean>,
+) :
+ AuthMethodBouncerViewModel(
+ isInputEnabled = isInputEnabled,
+ ) {
private val _password = MutableStateFlow("")
/** The password entered so far. */
@@ -47,7 +50,10 @@ class PasswordBouncerViewModel(
/** Notifies that the user has pressed the key for attempting to authenticate the password. */
fun onAuthenticateKeyPressed() {
- interactor.authenticate(password.value.toCharArray().toList())
+ if (!interactor.authenticate(password.value.toCharArray().toList())) {
+ showFailureAnimation()
+ }
+
_password.value = ""
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index 1b0b38ea6e9c..d9ef75db6103 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -37,8 +37,11 @@ class PatternBouncerViewModel(
private val applicationContext: Context,
applicationScope: CoroutineScope,
private val interactor: BouncerInteractor,
- override val isInputEnabled: StateFlow<Boolean>,
-) : AuthMethodBouncerViewModel {
+ isInputEnabled: StateFlow<Boolean>,
+) :
+ AuthMethodBouncerViewModel(
+ isInputEnabled = isInputEnabled,
+ ) {
/** The number of columns in the dot grid. */
val columnCount = 3
@@ -150,7 +153,11 @@ class PatternBouncerViewModel(
/** Notifies that the user has ended the drag gesture across the dot grid. */
fun onDragEnd() {
- interactor.authenticate(_selectedDots.value.map { it.toCoordinate() })
+ val isSuccessfullyAuthenticated =
+ interactor.authenticate(_selectedDots.value.map { it.toCoordinate() })
+ if (!isSuccessfullyAuthenticated) {
+ showFailureAnimation()
+ }
_dots.value = defaultDots()
_currentDot.value = null
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index 2a733d93b857..94d3d193e9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -16,41 +16,23 @@
package com.android.systemui.bouncer.ui.viewmodel
-import androidx.annotation.VisibleForTesting
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.util.kotlin.pairwise
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
/** Holds UI state and handles user input for the PIN code bouncer UI. */
class PinBouncerViewModel(
private val applicationScope: CoroutineScope,
private val interactor: BouncerInteractor,
- override val isInputEnabled: StateFlow<Boolean>,
-) : AuthMethodBouncerViewModel {
+ isInputEnabled: StateFlow<Boolean>,
+) :
+ AuthMethodBouncerViewModel(
+ isInputEnabled = isInputEnabled,
+ ) {
- private val entered = MutableStateFlow<List<Int>>(emptyList())
- /**
- * The length of the PIN digits that were input so far, two values are supplied the previous and
- * the current.
- */
- val pinLengths: StateFlow<Pair<Int, Int>> =
- entered
- .pairwise()
- .map { it.previousValue.size to it.newValue.size }
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = 0 to 0,
- )
- private var resetPinJob: Job? = null
+ private val mutablePinEntries = MutableStateFlow<List<EnteredKey>>(emptyList())
+ val pinEntries: StateFlow<List<EnteredKey>> = mutablePinEntries
/** Notifies that the UI has been shown to the user. */
fun onShown() {
@@ -59,44 +41,48 @@ class PinBouncerViewModel(
/** Notifies that the user clicked on a PIN button with the given digit value. */
fun onPinButtonClicked(input: Int) {
- resetPinJob?.cancel()
- resetPinJob = null
-
- if (entered.value.isEmpty()) {
+ if (mutablePinEntries.value.isEmpty()) {
interactor.clearMessage()
}
- entered.value += input
+ mutablePinEntries.value += EnteredKey(input)
}
/** Notifies that the user clicked the backspace button. */
fun onBackspaceButtonClicked() {
- if (entered.value.isEmpty()) {
+ if (mutablePinEntries.value.isEmpty()) {
return
}
-
- entered.value = entered.value.toMutableList().apply { removeLast() }
+ mutablePinEntries.value = mutablePinEntries.value.toMutableList().apply { removeLast() }
}
/** Notifies that the user long-pressed the backspace button. */
fun onBackspaceButtonLongPressed() {
- resetPinJob?.cancel()
- resetPinJob =
- applicationScope.launch {
- while (entered.value.isNotEmpty()) {
- onBackspaceButtonClicked()
- delay(BACKSPACE_LONG_PRESS_DELAY_MS)
- }
- }
+ mutablePinEntries.value = emptyList()
}
/** Notifies that the user clicked the "enter" button. */
fun onAuthenticateButtonClicked() {
- interactor.authenticate(entered.value)
- entered.value = emptyList()
- }
+ if (!interactor.authenticate(mutablePinEntries.value.map { it.input })) {
+ showFailureAnimation()
+ }
- companion object {
- @VisibleForTesting const val BACKSPACE_LONG_PRESS_DELAY_MS = 80L
+ mutablePinEntries.value = emptyList()
}
}
+
+private var nextSequenceNumber = 1
+
+/**
+ * The pin bouncer [input] as digits 0-9, together with a [sequenceNumber] to indicate the ordering.
+ *
+ * Since the model only allows appending/removing [EnteredKey]s from the end, the [sequenceNumber]
+ * is strictly increasing in input order of the pin, but not guaranteed to be monotonic or start at
+ * a specific number.
+ */
+data class EnteredKey
+internal constructor(val input: Int, val sequenceNumber: Int = nextSequenceNumber++) :
+ Comparable<EnteredKey> {
+ override fun compareTo(other: EnteredKey): Int =
+ compareValuesBy(this, other, EnteredKey::sequenceNumber)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
index de3a9901b8c4..4538a6ca7954 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
@@ -27,6 +27,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
/**
@@ -37,12 +38,14 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
private static final int DEFAULT_SEEKBAR_MAX = 6;
private static final int DEFAULT_SEEKBAR_PROGRESS = 0;
+ private static final int DEFAULT_SEEKBAR_TICK_MARK = 0;
private ViewGroup mIconStartFrame;
private ViewGroup mIconEndFrame;
private ImageView mIconStart;
private ImageView mIconEnd;
private SeekBar mSeekbar;
+ private int mSeekBarChangeMagnitude = 1;
private SeekBarChangeListener mSeekBarListener = new SeekBarChangeListener();
private String[] mStateLabels = null;
@@ -102,6 +105,15 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
context.getString(iconEndFrameContentDescriptionId);
mIconEndFrame.setContentDescription(contentDescription);
}
+ int tickMarkId = typedArray.getResourceId(
+ R.styleable.SeekBarWithIconButtonsView_Layout_tickMark,
+ DEFAULT_SEEKBAR_TICK_MARK);
+ if (tickMarkId != DEFAULT_SEEKBAR_TICK_MARK) {
+ mSeekbar.setTickMark(getResources().getDrawable(tickMarkId));
+ }
+ mSeekBarChangeMagnitude = typedArray.getInt(
+ R.styleable.SeekBarWithIconButtonsView_Layout_seekBarChangeMagnitude,
+ /* defValue= */ 1);
} else {
mSeekbar.setMax(DEFAULT_SEEKBAR_MAX);
setProgress(DEFAULT_SEEKBAR_PROGRESS);
@@ -112,7 +124,7 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
mIconStartFrame.setOnClickListener((view) -> {
final int progress = mSeekbar.getProgress();
if (progress > 0) {
- mSeekbar.setProgress(progress - 1);
+ mSeekbar.setProgress(progress - mSeekBarChangeMagnitude);
setIconViewAndFrameEnabled(mIconStart, mSeekbar.getProgress() > 0);
}
});
@@ -120,7 +132,7 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
mIconEndFrame.setOnClickListener((view) -> {
final int progress = mSeekbar.getProgress();
if (progress < mSeekbar.getMax()) {
- mSeekbar.setProgress(progress + 1);
+ mSeekbar.setProgress(progress + mSeekBarChangeMagnitude);
setIconViewAndFrameEnabled(mIconEnd, mSeekbar.getProgress() < mSeekbar.getMax());
}
});
@@ -183,6 +195,20 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
}
/**
+ * Gets max to the seekbar in the layout.
+ */
+ public int getMax() {
+ return mSeekbar.getMax();
+ }
+
+ /**
+ * @return the magnitude by which seekbar progress changes when start and end icons are clicked.
+ */
+ public int getChangeMagnitude() {
+ return mSeekBarChangeMagnitude;
+ }
+
+ /**
* Sets progress to the seekbar in the layout.
* If the progress is smaller than or equals to 0, the IconStart will be disabled. If the
* progress is larger than or equals to Max, the IconEnd will be disabled. The seekbar progress
@@ -193,6 +219,11 @@ public class SeekBarWithIconButtonsView extends LinearLayout {
updateIconViewIfNeeded(progress);
}
+ @VisibleForTesting
+ public int getProgress() {
+ return mSeekbar.getProgress();
+ }
+
private class SeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener = null;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
index a334c1ed2338..0bdc7f1dfb96 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
@@ -77,6 +77,10 @@ public class ComplicationTypesUpdater extends ConditionalCoreStartable {
Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
settingsObserver,
UserHandle.myUserId());
+ mSecureSettings.registerContentObserverForUser(
+ Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+ settingsObserver,
+ UserHandle.myUserId());
settingsObserver.onChange(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
index 8ba060e02c3d..1eba66765ce3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
@@ -35,6 +35,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.settings.UserTracker
+import com.android.systemui.util.ActivityTaskManagerProxy
import com.android.systemui.util.asIndenting
import com.android.systemui.util.indentIfPossible
import java.io.PrintWriter
@@ -67,6 +68,7 @@ class ControlsListingControllerImpl @VisibleForTesting constructor(
@Background private val backgroundExecutor: Executor,
private val serviceListingBuilder: (Context) -> ServiceListing,
private val userTracker: UserTracker,
+ private val activityTaskManagerProxy: ActivityTaskManagerProxy,
dumpManager: DumpManager,
private val featureFlags: FeatureFlags
) : ControlsListingController, Dumpable {
@@ -76,9 +78,18 @@ class ControlsListingControllerImpl @VisibleForTesting constructor(
context: Context,
@Background executor: Executor,
userTracker: UserTracker,
+ activityTaskManagerProxy: ActivityTaskManagerProxy,
dumpManager: DumpManager,
featureFlags: FeatureFlags
- ) : this(context, executor, ::createServiceListing, userTracker, dumpManager, featureFlags)
+ ) : this(
+ context,
+ executor,
+ ::createServiceListing,
+ userTracker,
+ activityTaskManagerProxy,
+ dumpManager,
+ featureFlags
+ )
private var serviceListing = serviceListingBuilder(context)
// All operations in background thread
@@ -113,7 +124,8 @@ class ControlsListingControllerImpl @VisibleForTesting constructor(
}
private fun updateServices(newServices: List<ControlsServiceInfo>) {
- if (featureFlags.isEnabled(Flags.USE_APP_PANELS)) {
+ if (featureFlags.isEnabled(Flags.USE_APP_PANELS) &&
+ activityTaskManagerProxy.supportsMultiWindow(context)) {
val allowAllApps = featureFlags.isEnabled(Flags.APP_PANELS_ALL_APPS_ALLOWED)
newServices.forEach {
it.resolvePanelActivity(allowAllApps) }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index e60063248fb0..fb19ac99d19e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -217,7 +217,6 @@ open class ControlsProviderSelectorActivity @Inject constructor(
)
}
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
- animateExitAndFinish()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 7cbd1f53612b..be50a1468f07 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -162,7 +162,11 @@ class DetailDialog(
broadcastSender.closeSystemDialogs()
// not sent as interactive, lest the higher-importance activity launch
// be impacted
- pendingIntent.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pendingIntent.send(options)
false
}
if (keyguardStateController.isUnlocked()) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index 116f3ca898c0..84cda5a541e3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.ui
+import android.app.ActivityOptions
import android.app.AlertDialog
import android.app.PendingIntent
import android.content.DialogInterface
@@ -74,7 +75,11 @@ class StatusBehavior : Behavior {
R.string.controls_open_app,
DialogInterface.OnClickListener { dialog, _ ->
try {
- cws.control?.getAppIntent()?.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ cws.control?.getAppIntent()?.send(options)
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
} catch (e: PendingIntent.CanceledException) {
cvh.setErrorStatus()
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 25634f009fc7..76002d3f9693 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -34,6 +34,7 @@ import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.keyboard.KeyboardUI
import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable
import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.KeyguardViewConfigurator
import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable
import com.android.systemui.log.SessionTracker
import com.android.systemui.media.RingtonePlayer
@@ -295,4 +296,9 @@ abstract class SystemUICoreStartableModule {
@IntoMap
@ClassKey(AssistantAttentionMonitor::class)
abstract fun bindAssistantAttentionMonitor(sysui: AssistantAttentionMonitor): CoreStartable
+
+ @Binds
+ @IntoMap
+ @ClassKey(KeyguardViewConfigurator::class)
+ abstract fun bindKeyguardViewConfigurator(impl: KeyguardViewConfigurator): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index b141db15ea0f..c2421dcbc6ca 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -19,7 +19,6 @@ package com.android.systemui.dreams;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_ENABLED;
import android.service.dreams.DreamService;
-import android.util.Log;
import androidx.annotation.NonNull;
@@ -52,7 +51,6 @@ import javax.inject.Named;
public class DreamOverlayStateController implements
CallbackController<DreamOverlayStateController.Callback> {
private static final String TAG = "DreamOverlayStateCtlr";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int STATE_DREAM_OVERLAY_ACTIVE = 1 << 0;
public static final int STATE_LOW_LIGHT_ACTIVE = 1 << 1;
@@ -110,13 +108,17 @@ public class DreamOverlayStateController implements
private final int mSupportedTypes;
+ private final DreamLogger mLogger;
+
@VisibleForTesting
@Inject
public DreamOverlayStateController(@Main Executor executor,
@Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ DreamLogger dreamLogger) {
mExecutor = executor;
mOverlayEnabled = overlayEnabled;
+ mLogger = dreamLogger;
mFeatureFlags = featureFlags;
if (mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)) {
mSupportedTypes = Complication.COMPLICATION_TYPE_NONE
@@ -124,9 +126,7 @@ public class DreamOverlayStateController implements
} else {
mSupportedTypes = Complication.COMPLICATION_TYPE_NONE;
}
- if (DEBUG) {
- Log.d(TAG, "Dream overlay enabled:" + mOverlayEnabled);
- }
+ mLogger.d(TAG, "Dream overlay enabled: " + mOverlayEnabled);
}
/**
@@ -134,18 +134,14 @@ public class DreamOverlayStateController implements
*/
public void addComplication(Complication complication) {
if (!mOverlayEnabled) {
- if (DEBUG) {
- Log.d(TAG,
- "Ignoring adding complication due to overlay disabled:" + complication);
- }
+ mLogger.d(TAG,
+ "Ignoring adding complication due to overlay disabled: " + complication);
return;
}
mExecutor.execute(() -> {
if (mComplications.add(complication)) {
- if (DEBUG) {
- Log.d(TAG, "addComplication: added " + complication);
- }
+ mLogger.d(TAG, "Added dream complication: " + complication);
mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
}
});
@@ -156,18 +152,14 @@ public class DreamOverlayStateController implements
*/
public void removeComplication(Complication complication) {
if (!mOverlayEnabled) {
- if (DEBUG) {
- Log.d(TAG,
- "Ignoring removing complication due to overlay disabled:" + complication);
- }
+ mLogger.d(TAG,
+ "Ignoring removing complication due to overlay disabled: " + complication);
return;
}
mExecutor.execute(() -> {
if (mComplications.remove(complication)) {
- if (DEBUG) {
- Log.d(TAG, "removeComplication: removed " + complication);
- }
+ mLogger.d(TAG, "Removed dream complication: " + complication);
mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
}
});
@@ -313,6 +305,7 @@ public class DreamOverlayStateController implements
* @param active {@code true} if overlay is active, {@code false} otherwise.
*/
public void setOverlayActive(boolean active) {
+ mLogger.d(TAG, "Dream overlay active: " + active);
modifyState(active ? OP_SET_STATE : OP_CLEAR_STATE, STATE_DREAM_OVERLAY_ACTIVE);
}
@@ -321,6 +314,8 @@ public class DreamOverlayStateController implements
* @param active {@code true} if low light mode is active, {@code false} otherwise.
*/
public void setLowLightActive(boolean active) {
+ mLogger.d(TAG, "Low light mode active: " + active);
+
if (isLowLightActive() && !active) {
// Notify that we're exiting low light only on the transition from active to not active.
mCallbacks.forEach(Callback::onExitLowLight);
@@ -351,6 +346,7 @@ public class DreamOverlayStateController implements
* @param hasAttention {@code true} if has the user's attention, {@code false} otherwise.
*/
public void setHasAssistantAttention(boolean hasAttention) {
+ mLogger.d(TAG, "Dream overlay has Assistant attention: " + hasAttention);
modifyState(hasAttention ? OP_SET_STATE : OP_CLEAR_STATE, STATE_HAS_ASSISTANT_ATTENTION);
}
@@ -359,6 +355,7 @@ public class DreamOverlayStateController implements
* @param visible {@code true} if the status bar is visible, {@code false} otherwise.
*/
public void setDreamOverlayStatusBarVisible(boolean visible) {
+ mLogger.d(TAG, "Dream overlay status bar visible: " + visible);
modifyState(
visible ? OP_SET_STATE : OP_CLEAR_STATE, STATE_DREAM_OVERLAY_STATUS_BAR_VISIBLE);
}
@@ -376,6 +373,7 @@ public class DreamOverlayStateController implements
*/
public void setAvailableComplicationTypes(@Complication.ComplicationType int types) {
mExecutor.execute(() -> {
+ mLogger.d(TAG, "Available complication types: " + types);
mAvailableComplicationTypes = types;
mCallbacks.forEach(Callback::onAvailableComplicationTypesChanged);
});
@@ -393,6 +391,7 @@ public class DreamOverlayStateController implements
*/
public void setShouldShowComplications(boolean shouldShowComplications) {
mExecutor.execute(() -> {
+ mLogger.d(TAG, "Should show complications: " + shouldShowComplications);
mShouldShowComplications = shouldShowComplications;
mCallbacks.forEach(Callback::onAvailableComplicationTypesChanged);
});
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 7c1bfeda30b2..1865c38632e5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -141,6 +141,20 @@ public class DreamOverlayStatusBarView extends ConstraintLayout {
mExtraSystemStatusViewGroup = findViewById(R.id.dream_overlay_extra_items);
}
+ protected static String getLoggableStatusIconType(@StatusIconType int type) {
+ return switch (type) {
+ case STATUS_ICON_NOTIFICATIONS -> "notifications";
+ case STATUS_ICON_WIFI_UNAVAILABLE -> "wifi_unavailable";
+ case STATUS_ICON_ALARM_SET -> "alarm_set";
+ case STATUS_ICON_CAMERA_DISABLED -> "camera_disabled";
+ case STATUS_ICON_MIC_DISABLED -> "mic_disabled";
+ case STATUS_ICON_MIC_CAMERA_DISABLED -> "mic_camera_disabled";
+ case STATUS_ICON_PRIORITY_MODE_ON -> "priority_mode_on";
+ case STATUS_ICON_ASSISTANT_ATTENTION_ACTIVE -> "assistant_attention_active";
+ default -> type + "(unknown)";
+ };
+ }
+
void showIcon(@StatusIconType int iconType, boolean show, @Nullable String contentDescription) {
View icon = mStatusIcons.get(iconType);
if (icon == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index c954f98ad36e..3a284083e844 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -61,6 +61,8 @@ import javax.inject.Inject;
*/
@DreamOverlayComponent.DreamOverlayScope
public class DreamOverlayStatusBarViewController extends ViewController<DreamOverlayStatusBarView> {
+ private static final String TAG = "DreamStatusBarCtrl";
+
private final ConnectivityManager mConnectivityManager;
private final TouchInsetManager.TouchInsetSession mTouchInsetSession;
private final NextAlarmController mNextAlarmController;
@@ -78,6 +80,7 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve
private final Executor mMainExecutor;
private final List<DreamOverlayStatusBarItemsProvider.StatusBarItem> mExtraStatusBarItems =
new ArrayList<>();
+ private final DreamLogger mLogger;
private boolean mIsAttached;
@@ -157,7 +160,8 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve
StatusBarWindowStateController statusBarWindowStateController,
DreamOverlayStatusBarItemsProvider statusBarItemsProvider,
DreamOverlayStateController dreamOverlayStateController,
- UserTracker userTracker) {
+ UserTracker userTracker,
+ DreamLogger dreamLogger) {
super(view);
mResources = resources;
mMainExecutor = mainExecutor;
@@ -173,6 +177,7 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve
mZenModeController = zenModeController;
mDreamOverlayStateController = dreamOverlayStateController;
mUserTracker = userTracker;
+ mLogger = dreamLogger;
// Register to receive show/hide updates for the system status bar. Our custom status bar
// needs to hide when the system status bar is showing to ovoid overlapping status bars.
@@ -341,6 +346,8 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve
@Nullable String contentDescription) {
mMainExecutor.execute(() -> {
if (mIsAttached) {
+ mLogger.d(TAG, (show ? "Showing" : "Hiding") + " dream status bar item: "
+ + DreamOverlayStatusBarView.getLoggableStatusIconType(iconType));
mView.showIcon(iconType, show, contentDescription);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 4f350db6ac8f..9b6ad19d3dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -134,7 +134,7 @@ object Flags {
// TODO(b/275694445): Tracking Bug
@JvmField
- val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = unreleasedFlag(208,
+ val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = releasedFlag(208,
"lockscreen_without_secure_lock_when_dreaming")
/**
@@ -173,7 +173,7 @@ object Flags {
*/
// TODO(b/281655028): Tracking bug
@JvmField
- val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = true)
+ val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false)
/** Flag to control the migration of face auth to modern architecture. */
// TODO(b/262838215): Tracking bug
@@ -355,7 +355,8 @@ object Flags {
// TODO(b/280426085): Tracking Bug
@JvmField
- val NEW_BLUETOOTH_REPOSITORY = unreleasedFlag(612, "new_bluetooth_repository")
+ val NEW_BLUETOOTH_REPOSITORY =
+ unreleasedFlag(612, "new_bluetooth_repository", teamfood = true)
// 700 - dialer/calls
// TODO(b/254512734): Tracking Bug
@@ -531,17 +532,10 @@ object Flags {
val ENABLE_PIP_APP_ICON_OVERLAY =
sysPropBooleanFlag(1115, "persist.wm.debug.enable_pip_app_icon_overlay", default = true)
- // TODO(b/272110828): Tracking bug
- @Keep
- @JvmField
- val ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
- sysPropBooleanFlag(
- 1116, "persist.wm.debug.enable_move_floating_window_in_tabletop", default = true)
-
// TODO(b/273443374): Tracking Bug
@Keep
@JvmField val LOCKSCREEN_LIVE_WALLPAPER =
- sysPropBooleanFlag(1117, "persist.wm.debug.lockscreen_live_wallpaper", default = false)
+ sysPropBooleanFlag(1117, "persist.wm.debug.lockscreen_live_wallpaper", default = true)
// TODO(b/281648899): Tracking bug
@Keep
@@ -635,6 +629,9 @@ object Flags {
// TODO(b/265944639): Tracking Bug
@JvmField val DUAL_SHADE = unreleasedFlag(1801, "dual_shade")
+ // TODO(b/283300105): Tracking Bug
+ @JvmField val SCENE_CONTAINER = unreleasedFlag(1802, "scene_container")
+
// 1900
@JvmField val NOTE_TASKS = releasedFlag(1900, "keycode_flag")
@@ -681,7 +678,7 @@ object Flags {
// TODO(b/283071711): Tracking bug
@JvmField
val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK =
- unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock")
+ releasedFlag(2401, "trim_resources_with_background_trim_on_lock")
// TODO:(b/283203305): Tracking bug
@JvmField
@@ -721,11 +718,6 @@ object Flags {
val LARGE_SHADE_GRANULAR_ALPHA_INTERPOLATION =
releasedFlag(2602, "large_shade_granular_alpha_interpolation")
- // TODO(b/272805037): Tracking Bug
- @JvmField
- val ADVANCED_VPN_ENABLED = releasedFlag(2800, name = "AdvancedVpn__enable_feature",
- namespace = "vpn")
-
// TODO(b/277201412): Tracking Bug
@JvmField
val SPLIT_SHADE_SUBPIXEL_OPTIMIZATION =
@@ -738,4 +730,9 @@ object Flags {
// TODO(b/283084712): Tracking Bug
@JvmField
val IMPROVED_HUN_ANIMATIONS = unreleasedFlag(283084712, "improved_hun_animations")
+
+ // TODO(b/283447257): Tracking bug
+ @JvmField
+ val BIGPICTURE_NOTIFICATION_LAZY_LOADING =
+ unreleasedFlag(283447257, "bigpicture_notification_lazy_loading")
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
index 757afb616fd1..67c85bd94bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -16,11 +16,19 @@
package com.android.systemui.keyguard;
+import android.annotation.IntDef;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
-import android.os.Trace;
+import android.os.TraceNameSupplier;
+
+import androidx.annotation.NonNull;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import javax.inject.Inject;
@@ -29,7 +37,6 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class KeyguardLifecyclesDispatcher {
-
static final int SCREEN_TURNING_ON = 0;
static final int SCREEN_TURNED_ON = 1;
static final int SCREEN_TURNING_OFF = 2;
@@ -39,19 +46,46 @@ public class KeyguardLifecyclesDispatcher {
static final int FINISHED_WAKING_UP = 5;
static final int STARTED_GOING_TO_SLEEP = 6;
static final int FINISHED_GOING_TO_SLEEP = 7;
- private static final String TAG = "KeyguardLifecyclesDispatcher";
- private final ScreenLifecycle mScreenLifecycle;
- private final WakefulnessLifecycle mWakefulnessLifecycle;
+ @IntDef({
+ SCREEN_TURNING_ON,
+ SCREEN_TURNED_ON,
+ SCREEN_TURNING_OFF,
+ SCREEN_TURNED_OFF,
+ STARTED_WAKING_UP,
+ FINISHED_WAKING_UP,
+ STARTED_GOING_TO_SLEEP,
+ FINISHED_GOING_TO_SLEEP,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface KeyguardLifecycleMessageType {
+ }
+
+ private static String getNameOfMessage(@KeyguardLifecycleMessageType int what) {
+ return switch (what) {
+ case SCREEN_TURNING_ON -> "SCREEN_TURNING_ON";
+ case SCREEN_TURNED_ON -> "SCREEN_TURNED_ON";
+ case SCREEN_TURNING_OFF -> "SCREEN_TURNING_OFF";
+ case SCREEN_TURNED_OFF -> "SCREEN_TURNED_OFF";
+ case STARTED_WAKING_UP -> "STARTED_WAKING_UP";
+ case FINISHED_WAKING_UP -> "FINISHED_WAKING_UP";
+ case STARTED_GOING_TO_SLEEP -> "STARTED_GOING_TO_SLEEP";
+ case FINISHED_GOING_TO_SLEEP -> "FINISHED_GOING_TO_SLEEP";
+ default -> "UNKNOWN";
+ };
+ }
+
+ private final Handler mHandler;
@Inject
- public KeyguardLifecyclesDispatcher(ScreenLifecycle screenLifecycle,
+ public KeyguardLifecyclesDispatcher(
+ @Main Looper mainLooper,
+ ScreenLifecycle screenLifecycle,
WakefulnessLifecycle wakefulnessLifecycle) {
- mScreenLifecycle = screenLifecycle;
- mWakefulnessLifecycle = wakefulnessLifecycle;
+ mHandler = new KeyguardLifecycleHandler(mainLooper, screenLifecycle, wakefulnessLifecycle);
}
- void dispatch(int what) {
+ void dispatch(@KeyguardLifecycleMessageType int what) {
mHandler.obtainMessage(what).sendToTarget();
}
@@ -60,7 +94,7 @@ public class KeyguardLifecyclesDispatcher {
* @param pmReason Reason this message was triggered - this should be a value from either
* {@link PowerManager.WakeReason} or {@link PowerManager.GoToSleepReason}.
*/
- void dispatch(int what, int pmReason) {
+ void dispatch(@KeyguardLifecycleMessageType int what, int pmReason) {
final Message message = mHandler.obtainMessage(what);
message.arg1 = pmReason;
message.sendToTarget();
@@ -70,44 +104,48 @@ public class KeyguardLifecyclesDispatcher {
* @param what Message to send.
* @param object Object to send with the message
*/
- void dispatch(int what, Object object) {
+ void dispatch(@KeyguardLifecycleMessageType int what, Object object) {
mHandler.obtainMessage(what, object).sendToTarget();
}
- private Handler mHandler = new Handler() {
+ private static class KeyguardLifecycleHandler extends Handler {
+ private static final String TAG = "KeyguardLifecycleHandler";
+ private final ScreenLifecycle mScreenLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
+
+ public KeyguardLifecycleHandler(Looper looper,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle) {
+ super(looper);
+ mScreenLifecycle = screenLifecycle;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
+ }
+
+ @NonNull
@Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SCREEN_TURNING_ON:
- Trace.beginSection("KeyguardLifecyclesDispatcher#SCREEN_TURNING_ON");
- mScreenLifecycle.dispatchScreenTurningOn();
- Trace.endSection();
- break;
- case SCREEN_TURNED_ON:
- mScreenLifecycle.dispatchScreenTurnedOn();
- break;
- case SCREEN_TURNING_OFF:
- mScreenLifecycle.dispatchScreenTurningOff();
- break;
- case SCREEN_TURNED_OFF:
- mScreenLifecycle.dispatchScreenTurnedOff();
- break;
- case STARTED_WAKING_UP:
- mWakefulnessLifecycle.dispatchStartedWakingUp(msg.arg1 /* pmReason */);
- break;
- case FINISHED_WAKING_UP:
- mWakefulnessLifecycle.dispatchFinishedWakingUp();
- break;
- case STARTED_GOING_TO_SLEEP:
- mWakefulnessLifecycle.dispatchStartedGoingToSleep(msg.arg1 /* pmReason */);
- break;
- case FINISHED_GOING_TO_SLEEP:
- mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
- break;
- default:
- throw new IllegalArgumentException("Unknown message: " + msg);
+ public String getTraceName(@NonNull Message msg) {
+ if (msg.getCallback() instanceof TraceNameSupplier || msg.getCallback() != null) {
+ return super.getTraceName(msg);
}
+ return TAG + "#" + getNameOfMessage(msg.what);
}
- };
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case SCREEN_TURNING_ON -> mScreenLifecycle.dispatchScreenTurningOn();
+ case SCREEN_TURNED_ON -> mScreenLifecycle.dispatchScreenTurnedOn();
+ case SCREEN_TURNING_OFF -> mScreenLifecycle.dispatchScreenTurningOff();
+ case SCREEN_TURNED_OFF -> mScreenLifecycle.dispatchScreenTurnedOff();
+ case STARTED_WAKING_UP ->
+ mWakefulnessLifecycle.dispatchStartedWakingUp(msg.arg1 /* pmReason */);
+ case FINISHED_WAKING_UP -> mWakefulnessLifecycle.dispatchFinishedWakingUp();
+ case STARTED_GOING_TO_SLEEP ->
+ mWakefulnessLifecycle.dispatchStartedGoingToSleep(msg.arg1 /* pmReason */);
+ case FINISHED_GOING_TO_SLEEP ->
+ mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
+ default -> throw new IllegalArgumentException("Unknown message: " + msg);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 51a29b00f9db..5a8c2253b185 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TransitionFlags;
import static android.view.WindowManager.TransitionOldType;
import static android.view.WindowManager.TransitionType;
@@ -49,6 +50,7 @@ import android.os.RemoteException;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.RotationUtils;
import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -62,6 +64,7 @@ import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
import android.window.TransitionInfo;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -72,6 +75,7 @@ import com.android.systemui.SystemUIApplication;
import com.android.systemui.settings.DisplayTracker;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.CounterRotator;
import com.android.wm.shell.util.TransitionUtil;
import java.util.ArrayList;
@@ -102,7 +106,8 @@ public class KeyguardService extends Service {
}
private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
- SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
+ SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
+ CounterRotator counterWallpaper) {
final ArrayList<RemoteAnimationTarget> out = new ArrayList<>();
for (int i = 0; i < info.getChanges().size(); i++) {
boolean changeIsWallpaper =
@@ -121,6 +126,10 @@ public class KeyguardService extends Service {
}
}
+ // Avoid wrapping non-task and non-wallpaper changes as they don't need to animate
+ // for keyguard unlock animation.
+ if (taskId < 0 && !wallpapers) continue;
+
final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
// wallpapers go into the "below" layer space
info.getChanges().size() - i,
@@ -128,6 +137,25 @@ public class KeyguardService extends Service {
(change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
info, t, leashMap);
+ if (changeIsWallpaper) {
+ int rotateDelta = RotationUtils.deltaRotation(change.getStartRotation(),
+ change.getEndRotation());
+ if (rotateDelta != 0 && change.getParent() != null
+ && change.getMode() == TRANSIT_TO_BACK) {
+ final TransitionInfo.Change parent = info.getChange(change.getParent());
+ if (parent != null) {
+ float displayW = parent.getEndAbsBounds().width();
+ float displayH = parent.getEndAbsBounds().height();
+ counterWallpaper.setup(t, parent.getLeash(), rotateDelta, displayW,
+ displayH);
+ }
+ if (counterWallpaper.getSurface() != null) {
+ t.setLayer(counterWallpaper.getSurface(), -1);
+ counterWallpaper.addChild(t, leashMap.get(change.getLeash()));
+ }
+ }
+ }
+
out.add(target);
}
return out.toArray(new RemoteAnimationTarget[out.size()]);
@@ -140,8 +168,8 @@ public class KeyguardService extends Service {
return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER
: TRANSIT_OLD_KEYGUARD_GOING_AWAY;
} else if (type == TRANSIT_KEYGUARD_OCCLUDE) {
- boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo.topActivityType
- == WindowConfiguration.ACTIVITY_TYPE_DREAM;
+ boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo != null
+ && apps[0].taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM;
if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
return TRANSIT_OLD_KEYGUARD_OCCLUDE;
} else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) {
@@ -156,64 +184,63 @@ public class KeyguardService extends Service {
// Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
public static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
return new IRemoteTransition.Stub() {
- final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
- new ArrayMap<>();
+
private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();
+ private final CounterRotator mCounterRotator = new CounterRotator();
+
+
+ @GuardedBy("mLeashMap")
+ private IRemoteTransitionFinishedCallback mFinishCallback = null;
@Override
public void startAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
throws RemoteException {
Slog.d(TAG, "Starts IRemoteAnimationRunner: info=" + info);
- final RemoteAnimationTarget[] apps =
- wrap(info, false /* wallpapers */, t, mLeashMap);
- final RemoteAnimationTarget[] wallpapers =
- wrap(info, true /* wallpapers */, t, mLeashMap);
- final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
-
- // Set alpha back to 1 for the independent changes because we will be animating
- // children instead.
- for (TransitionInfo.Change chg : info.getChanges()) {
- if (TransitionInfo.isIndependent(chg, info)) {
- t.setAlpha(chg.getLeash(), 1.f);
+
+ synchronized (mLeashMap) {
+ final RemoteAnimationTarget[] apps =
+ wrap(info, false /* wallpapers */, t, mLeashMap, mCounterRotator);
+ final RemoteAnimationTarget[] wallpapers =
+ wrap(info, true /* wallpapers */, t, mLeashMap, mCounterRotator);
+ final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
+
+ // Set alpha back to 1 for the independent changes because we will be animating
+ // children instead.
+ for (TransitionInfo.Change chg : info.getChanges()) {
+ if (TransitionInfo.isIndependent(chg, info)) {
+ t.setAlpha(chg.getLeash(), 1.f);
+ }
}
- }
- initAlphaForAnimationTargets(t, apps);
- initAlphaForAnimationTargets(t, wallpapers);
- t.apply();
- synchronized (mFinishCallbacks) {
- mFinishCallbacks.put(transition, finishCallback);
- }
- runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps),
- apps, wallpapers, nonApps,
- new IRemoteAnimationFinishedCallback.Stub() {
- @Override
- public void onAnimationFinished() throws RemoteException {
- synchronized (mFinishCallbacks) {
- if (mFinishCallbacks.remove(transition) == null) return;
+ initAlphaForAnimationTargets(t, apps);
+ initAlphaForAnimationTargets(t, wallpapers);
+ t.apply();
+ mFinishCallback = finishCallback;
+ runner.onAnimationStart(
+ getTransitionOldType(info.getType(), info.getFlags(), apps),
+ apps, wallpapers, nonApps,
+ new IRemoteAnimationFinishedCallback.Stub() {
+ @Override
+ public void onAnimationFinished() throws RemoteException {
+ synchronized (mLeashMap) {
+ Slog.d(TAG, "Finish IRemoteAnimationRunner.");
+ finish();
+ }
}
- info.releaseAllSurfaces();
- Slog.d(TAG, "Finish IRemoteAnimationRunner.");
- finishCallback.onTransitionFinished(null /* wct */, null /* t */);
}
- }
- );
+ );
+ }
}
public void mergeAnimation(IBinder candidateTransition, TransitionInfo candidateInfo,
SurfaceControl.Transaction candidateT, IBinder currentTransition,
- IRemoteTransitionFinishedCallback candidateFinishCallback) {
+ IRemoteTransitionFinishedCallback candidateFinishCallback)
+ throws RemoteException {
try {
- final IRemoteTransitionFinishedCallback currentFinishCB;
- synchronized (mFinishCallbacks) {
- currentFinishCB = mFinishCallbacks.remove(currentTransition);
+ synchronized (mLeashMap) {
+ runner.onAnimationCancelled();
+ finish();
}
- if (currentFinishCB == null) {
- Slog.e(TAG, "Called mergeAnimation, but finish callback is missing");
- return;
- }
- runner.onAnimationCancelled();
- currentFinishCB.onTransitionFinished(null /* wct */, null /* t */);
} catch (RemoteException e) {
// nothing, we'll just let it finish on its own I guess.
}
@@ -226,6 +253,24 @@ public class KeyguardService extends Service {
t.setAlpha(target.leash, 0.f);
}
}
+
+ @GuardedBy("mLeashMap")
+ private void finish() throws RemoteException {
+ SurfaceControl.Transaction finishTransaction = null;
+ if (mCounterRotator.getSurface() != null
+ && mCounterRotator.getSurface().isValid()) {
+ finishTransaction = new SurfaceControl.Transaction();
+ mCounterRotator.cleanUp(finishTransaction);
+ }
+ mLeashMap.clear();
+ final IRemoteTransitionFinishedCallback finishCallback = mFinishCallback;
+ if (finishCallback != null) {
+ mFinishCallback = null;
+ finishCallback.onTransitionFinished(null /* wct */, finishTransaction);
+ } else if (finishTransaction != null) {
+ finishTransaction.apply();
+ }
+ }
};
}
@@ -295,46 +340,6 @@ public class KeyguardService extends Service {
}
}
- final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() {
- @Override
- public void startAnimation(IBinder transition, TransitionInfo info,
- SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
- throws RemoteException {
- t.apply();
- mBinder.setOccluded(true /* isOccluded */, true /* animate */);
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
- info.releaseAllSurfaces();
- }
-
- @Override
- public void mergeAnimation(IBinder transition, TransitionInfo info,
- SurfaceControl.Transaction t, IBinder mergeTarget,
- IRemoteTransitionFinishedCallback finishCallback) {
- t.close();
- info.releaseAllSurfaces();
- }
- };
-
- final IRemoteTransition mUnoccludeAnimation = new IRemoteTransition.Stub() {
- @Override
- public void startAnimation(IBinder transition, TransitionInfo info,
- SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
- throws RemoteException {
- t.apply();
- mBinder.setOccluded(false /* isOccluded */, true /* animate */);
- finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
- info.releaseAllSurfaces();
- }
-
- @Override
- public void mergeAnimation(IBinder transition, TransitionInfo info,
- SurfaceControl.Transaction t, IBinder mergeTarget,
- IRemoteTransitionFinishedCallback finishCallback) {
- t.close();
- info.releaseAllSurfaces();
- }
- };
-
private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
private static final String TRACK_NAME = "IKeyguardService";
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 122e25975837..c706363c9454 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -33,10 +33,10 @@ import android.view.SyncRtSurfaceTransactionApplier
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.core.math.MathUtils
+import com.android.app.animation.Interpolators
import com.android.internal.R
import com.android.keyguard.KeyguardClockSwitchController
import com.android.keyguard.KeyguardViewController
-import com.android.app.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -433,7 +433,14 @@ class KeyguardUnlockAnimationController @Inject constructor(
// animate state.
if (!keyguardStateController.isKeyguardGoingAway &&
willUnlockWithInWindowLauncherAnimations) {
- launcherUnlockController?.setUnlockAmount(1f, true /* forceIfAnimating */)
+ try {
+ launcherUnlockController?.setUnlockAmount(1f, true /* forceIfAnimating */)
+ } catch (e: DeadObjectException) {
+ Log.e(TAG, "launcherUnlockAnimationController was dead, but non-null in " +
+ "onKeyguardGoingAwayChanged(). Catching exception as this should mean " +
+ "Launcher is in the process of being destroyed, but the IPC to System UI " +
+ "telling us hasn't arrived yet.")
+ }
}
}
@@ -637,7 +644,9 @@ class KeyguardUnlockAnimationController @Inject constructor(
* Unlock to the launcher, using in-window animations, and the smartspace shared element
* transition if possible.
*/
- private fun unlockToLauncherWithInWindowAnimations() {
+
+ @VisibleForTesting
+ fun unlockToLauncherWithInWindowAnimations() {
setSurfaceBehindAppearAmount(1f, wallpapers = false)
try {
@@ -662,10 +671,28 @@ class KeyguardUnlockAnimationController @Inject constructor(
// Now that the Launcher surface (with its smartspace positioned identically to ours) is
// visible, hide our smartspace.
- lockscreenSmartspace?.visibility = View.INVISIBLE
+ if (lockscreenSmartspace?.visibility == View.VISIBLE) {
+ lockscreenSmartspace?.visibility = View.INVISIBLE
+ }
- // Start an animation for the wallpaper, which will finish keyguard exit when it completes.
- fadeInWallpaper()
+ // As soon as the shade has animated out of the way, start the canned unlock animation,
+ // which will finish keyguard exit when it completes. The in-window animations in the
+ // Launcher window will end on their own.
+ handler.postDelayed({
+ if (keyguardViewMediator.get().isShowingAndNotOccluded &&
+ !keyguardStateController.isKeyguardGoingAway) {
+ Log.e(TAG, "Finish keyguard exit animation delayed Runnable ran, but we are " +
+ "showing and not going away.")
+ return@postDelayed
+ }
+
+ if (wallpaperTargets != null) {
+ fadeInWallpaper()
+ } else {
+ keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
+ false /* cancelled */)
+ }
+ }, CANNED_UNLOCK_START_DELAY)
}
/**
@@ -914,7 +941,9 @@ class KeyguardUnlockAnimationController @Inject constructor(
willUnlockWithSmartspaceTransition = false
// The lockscreen surface is gone, so it is now safe to re-show the smartspace.
- lockscreenSmartspace?.visibility = View.VISIBLE
+ if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
+ lockscreenSmartspace?.visibility = View.VISIBLE
+ }
listeners.forEach { it.onUnlockAnimationFinished() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
new file mode 100644
index 000000000000..05c23aefe974
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard
+
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.CoreStartable
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
+import com.android.systemui.keyguard.ui.view.KeyguardRootView
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
+import com.android.systemui.shade.NotificationShadeWindowView
+import com.android.systemui.statusbar.KeyguardIndicationController
+import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
+
+/** Binds keyguard views on startup, and also exposes methods to allow rebinding if views change */
+@SysUISingleton
+class KeyguardViewConfigurator
+@Inject
+constructor(
+ private val keyguardRootView: KeyguardRootView,
+ private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel,
+ private val notificationShadeWindowView: NotificationShadeWindowView,
+ private val featureFlags: FeatureFlags,
+ private val indicationController: KeyguardIndicationController,
+) : CoreStartable {
+
+ private var indicationAreaHandle: DisposableHandle? = null
+
+ override fun start() {
+ bindIndicationArea(
+ notificationShadeWindowView.requireViewById(R.id.notification_panel) as ViewGroup
+ )
+ }
+
+ fun bindIndicationArea(legacyParent: ViewGroup) {
+ indicationAreaHandle?.dispose()
+
+ // At startup, 2 views with the ID `R.id.keyguard_indication_area` will be available.
+ // Disable one of them
+ if (featureFlags.isEnabled(Flags.MIGRATE_INDICATION_AREA)) {
+ legacyParent.requireViewById<View>(R.id.keyguard_indication_area).let {
+ legacyParent.removeView(it)
+ }
+ } else {
+ keyguardRootView.findViewById<View?>(R.id.keyguard_indication_area)?.let {
+ keyguardRootView.removeView(it)
+ }
+ }
+
+ indicationAreaHandle =
+ KeyguardIndicationAreaBinder.bind(
+ notificationShadeWindowView,
+ keyguardIndicationAreaViewModel,
+ indicationController
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 45e4623c7e27..81f325f53f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -17,6 +17,8 @@
package com.android.systemui.keyguard;
import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
+import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
@@ -70,7 +72,6 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
@@ -93,7 +94,6 @@ import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
-import android.window.IRemoteTransition;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -154,6 +154,9 @@ import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.settings.SystemSettings;
+import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.keyguard.KeyguardTransitions;
import dagger.Lazy;
@@ -161,7 +164,6 @@ import dagger.Lazy;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Optional;
import java.util.concurrent.Executor;
/**
@@ -215,7 +217,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final static String TAG = "KeyguardViewMediator";
- private static final String DELAYED_KEYGUARD_ACTION =
+ public static final String DELAYED_KEYGUARD_ACTION =
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
private static final String DELAYED_LOCK_PROFILE_ACTION =
"com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
@@ -250,7 +252,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
* turning on the keyguard (i.e, the user has this much time to turn
* the screen back on without having to face the keyguard).
*/
- private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
+ public static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
/**
* How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
@@ -306,6 +308,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
/** UserSwitcherController for creating guest user on boot complete */
private final UserSwitcherController mUserSwitcherController;
+ private final SecureSettings mSecureSettings;
+ private final SystemSettings mSystemSettings;
+ private final SystemClock mSystemClock;
/**
* Used to keep the device awake while to ensure the keyguard finishes opening before
@@ -1253,7 +1258,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
Lazy<ScrimController> scrimControllerLazy,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ SecureSettings secureSettings,
+ SystemSettings systemSettings,
+ SystemClock systemClock) {
mContext = context;
mUserTracker = userTracker;
mFalsingCollector = falsingCollector;
@@ -1267,6 +1275,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mPM = powerManager;
mTrustManager = trustManager;
mUserSwitcherController = userSwitcherController;
+ mSecureSettings = secureSettings;
+ mSystemSettings = systemSettings;
+ mSystemClock = systemClock;
mStatusBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mKeyguardDisplayManager = keyguardDisplayManager;
@@ -1316,7 +1327,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
public void userActivity() {
- mPM.userActivity(SystemClock.uptimeMillis(), false);
+ mPM.userActivity(mSystemClock.uptimeMillis(), false);
}
private void setupLocked() {
@@ -1502,7 +1513,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (cameraGestureTriggered) {
// Just to make sure, make sure the device is awake.
- mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
+ mContext.getSystemService(PowerManager.class).wakeUp(mSystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
setPendingLock(false);
@@ -1599,12 +1610,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// to enable it a bit later (i.e, give the user a chance
// to turn the screen back on within a certain window without
// having to unlock the screen)
- final ContentResolver cr = mContext.getContentResolver();
// From SecuritySettings
- final long lockAfterTimeout = Settings.Secure.getInt(cr,
- Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+ final long lockAfterTimeout = mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT,
+ userId);
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
@@ -1616,8 +1626,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
timeout = lockAfterTimeout;
} else {
// From DisplaySettings
- long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
- KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+ long displayTimeout = mSystemSettings.getIntForUser(SCREEN_OFF_TIMEOUT,
+ KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT,
+ userId);
// policy in effect. Make sure we don't go beyond policy limit.
displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
@@ -1638,7 +1649,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private void doKeyguardLaterLocked(long timeout) {
// Lock in the future
- long when = SystemClock.elapsedRealtime() + timeout;
+ long when = mSystemClock.elapsedRealtime() + timeout;
Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
intent.setPackage(mContext.getPackageName());
intent.putExtra("seq", mDelayedShowingSequence);
@@ -1660,7 +1671,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (userTimeout == 0) {
doKeyguardForChildProfilesLocked();
} else {
- long userWhen = SystemClock.elapsedRealtime() + userTimeout;
+ long userWhen = mSystemClock.elapsedRealtime() + userTimeout;
Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
lockIntent.setPackage(mContext.getPackageName());
lockIntent.putExtra("seq", mDelayedProfileShowingSequence);
@@ -2468,8 +2479,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private void playSound(int soundId) {
if (soundId == 0) return;
- final ContentResolver cr = mContext.getContentResolver();
- if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
+ int lockscreenSoundsEnabled = mSystemSettings.getIntForUser(LOCKSCREEN_SOUNDS_ENABLED, 1,
+ KeyguardUpdateMonitor.getCurrentUser());
+ if (lockscreenSoundsEnabled == 1) {
mLockSounds.stop(mLockSoundStreamId);
// Init mAudioManager
@@ -2644,7 +2656,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// It's possible that the device was unlocked (via BOUNCER) while dozing. It's time to
// wake up.
if (mAodShowing) {
- mPM.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"com.android.systemui:BOUNCER_DOZING");
}
@@ -2659,7 +2671,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// TODO(bc-unlock): Fill parameters
mNotificationShadeWindowControllerLazy.get().batchApplyWindowLayoutParams(() -> {
handleStartKeyguardExitAnimation(
- SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
+ mSystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */,
null /* nonApps */, null /* finishedCallback */);
});
@@ -2668,7 +2680,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// It's possible that the device was unlocked (via BOUNCER or Fingerprint) while
// dreaming. It's time to wake up.
if (mDreamOverlayShowing) {
- mPM.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"com.android.systemui:UNLOCK_DREAMING");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
index d8affa4d6c21..1978b3d048b7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
@@ -139,7 +139,8 @@ constructor(
if (dozeDisabledAndScreenOff || dozeEnabledAndDozeAnimationCompleted) {
Trace.beginSection("ResourceTrimmer#trimMemory")
Log.d(LOG_TAG, "SysUI asleep, trimming memory.")
- globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND)
+ globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+ globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
Trace.endSection()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index d7c039d9b519..1c5bb5f4efaf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -64,6 +64,9 @@ import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.settings.SystemSettings;
+import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.keyguard.KeyguardTransitions;
import dagger.Lazy;
@@ -128,7 +131,10 @@ public class KeyguardModule {
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
Lazy<ScrimController> scrimControllerLazy,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ SecureSettings secureSettings,
+ SystemSettings systemSettings,
+ SystemClock systemClock) {
return new KeyguardViewMediator(
context,
uiEventLogger,
@@ -162,7 +168,10 @@ public class KeyguardModule {
notificationShadeWindowController,
activityLaunchAnimator,
scrimControllerLazy,
- featureFlags);
+ featureFlags,
+ secureSettings,
+ systemSettings,
+ systemClock);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
index c9f645dddd8d..af0abdff0c62 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
@@ -52,8 +52,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.CAMERA
- override val pickerName: String
- get() = context.getString(R.string.accessibility_camera_button)
+ override fun pickerName(): String = context.getString(R.string.accessibility_camera_button)
override val pickerIconResourceId: Int
get() = R.drawable.ic_camera
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index ef0c9a175141..16385ec59aa7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -99,7 +99,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.DO_NOT_DISTURB
- override val pickerName: String = context.getString(R.string.quick_settings_dnd_label)
+ override fun pickerName(): String = context.getString(R.string.quick_settings_dnd_label)
override val pickerIconResourceId: Int = R.drawable.ic_do_not_disturb
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
index 3412f35669e3..ed8823a53fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
@@ -75,8 +75,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.FLASHLIGHT
- override val pickerName: String
- get() = context.getString(R.string.quick_settings_flashlight_label)
+ override fun pickerName(): String = context.getString(R.string.quick_settings_flashlight_label)
override val pickerIconResourceId: Int
get() = R.drawable.ic_flashlight_off
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index a1e9137d1764..abb63c4d34ce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -54,7 +54,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
- override val pickerName: String by lazy { context.getString(component.getTileTitleId()) }
+ override fun pickerName(): String = context.getString(component.getTileTitleId())
override val pickerIconResourceId: Int by lazy { component.getTileImageId() }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index e32edcb010e8..28dc5bdcc45f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -31,8 +31,6 @@ interface KeyguardQuickAffordanceConfig {
/** Unique identifier for this quick affordance. It must be globally unique. */
val key: String
- val pickerName: String
-
val pickerIconResourceId: Int
/**
@@ -43,6 +41,12 @@ interface KeyguardQuickAffordanceConfig {
val lockScreenState: Flow<LockScreenState>
/**
+ * Returns a user-visible [String] that should be shown as the name for the option in the
+ * wallpaper picker / settings app to select this quick affordance.
+ */
+ fun pickerName(): String
+
+ /**
* Returns the [PickerScreenState] representing the affordance in the settings or selector
* experience.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
index 356a8fb65883..4dad17907aca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
@@ -47,7 +47,7 @@ import kotlinx.coroutines.flow.onStart
class KeyguardQuickAffordanceLocalUserSelectionManager
@Inject
constructor(
- @Application context: Context,
+ @Application private val context: Context,
private val userFileManager: UserFileManager,
private val userTracker: UserTracker,
broadcastDispatcher: BroadcastDispatcher,
@@ -126,6 +126,11 @@ constructor(
}
override fun getSelections(): Map<String, List<String>> {
+ // If the custom shortcuts feature is not enabled, ignore prior selections and use defaults
+ if (!context.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled)) {
+ return defaults
+ }
+
val slotKeys = sharedPrefs.all.keys.filter { it.startsWith(KEY_PREFIX_SLOT) }
val result =
slotKeys
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
index da91572894f3..250356819baf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
@@ -34,6 +34,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.RingerModeTracker
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
@@ -45,30 +46,32 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import javax.inject.Inject
@SysUISingleton
-class MuteQuickAffordanceConfig @Inject constructor(
- context: Context,
- private val userTracker: UserTracker,
- private val userFileManager: UserFileManager,
- private val ringerModeTracker: RingerModeTracker,
- private val audioManager: AudioManager,
- @Application private val coroutineScope: CoroutineScope,
- @Main private val mainDispatcher: CoroutineDispatcher,
- @Background private val backgroundDispatcher: CoroutineDispatcher,
+class MuteQuickAffordanceConfig
+@Inject
+constructor(
+ private val context: Context,
+ private val userTracker: UserTracker,
+ private val userFileManager: UserFileManager,
+ private val ringerModeTracker: RingerModeTracker,
+ private val audioManager: AudioManager,
+ @Application private val coroutineScope: CoroutineScope,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
) : KeyguardQuickAffordanceConfig {
private var previousNonSilentMode: Int = DEFAULT_LAST_NON_SILENT_VALUE
override val key: String = BuiltInKeyguardQuickAffordanceKeys.MUTE
- override val pickerName: String = context.getString(R.string.volume_ringer_status_silent)
+ override fun pickerName(): String = context.getString(R.string.volume_ringer_status_silent)
override val pickerIconResourceId: Int = R.drawable.ic_notifications_silence
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
- ringerModeTracker.ringerModeInternal.asFlow()
+ ringerModeTracker.ringerModeInternal
+ .asFlow()
.onStart { getLastNonSilentRingerMode() }
.distinctUntilChanged()
.onEach { mode ->
@@ -78,17 +81,14 @@ class MuteQuickAffordanceConfig @Inject constructor(
}
}
.map { mode ->
- val (activationState, contentDescriptionRes) = when {
- audioManager.isVolumeFixed ->
- ActivationState.NotSupported to
- R.string.volume_ringer_hint_mute
- mode == AudioManager.RINGER_MODE_SILENT ->
- ActivationState.Active to
- R.string.volume_ringer_hint_mute
- else ->
- ActivationState.Inactive to
- R.string.volume_ringer_hint_unmute
- }
+ val (activationState, contentDescriptionRes) =
+ when {
+ audioManager.isVolumeFixed ->
+ ActivationState.NotSupported to R.string.volume_ringer_hint_mute
+ mode == AudioManager.RINGER_MODE_SILENT ->
+ ActivationState.Active to R.string.volume_ringer_hint_mute
+ else -> ActivationState.Inactive to R.string.volume_ringer_hint_unmute
+ }
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
Icon.Resource(
@@ -130,32 +130,35 @@ class MuteQuickAffordanceConfig @Inject constructor(
}
/**
- * Gets the last non-silent ringer mode from shared-preferences if it exists. This is
- * cached by [MuteQuickAffordanceCoreStartable] while this affordance is selected
+ * Gets the last non-silent ringer mode from shared-preferences if it exists. This is cached by
+ * [MuteQuickAffordanceCoreStartable] while this affordance is selected
*/
private suspend fun getLastNonSilentRingerMode(): Int =
withContext(backgroundDispatcher) {
- userFileManager.getSharedPreferences(
+ userFileManager
+ .getSharedPreferences(
MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME,
Context.MODE_PRIVATE,
userTracker.userId
- ).getInt(
+ )
+ .getInt(
LAST_NON_SILENT_RINGER_MODE_KEY,
ringerModeTracker.ringerModeInternal.value ?: DEFAULT_LAST_NON_SILENT_VALUE
- )
+ )
}
private fun <T> LiveData<T>.asFlow(): Flow<T?> =
conflatedCallbackFlow {
- val observer = Observer { value: T -> trySend(value) }
- observeForever(observer)
- send(value)
- awaitClose { removeObserver(observer) }
- }.flowOn(mainDispatcher)
+ val observer = Observer { value: T -> trySend(value) }
+ observeForever(observer)
+ send(value)
+ awaitClose { removeObserver(observer) }
+ }
+ .flowOn(mainDispatcher)
companion object {
const val LAST_NON_SILENT_RINGER_MODE_KEY = "key_last_non_silent_ringer_mode"
const val MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME = "quick_affordance_mute_ringer_mode_cache"
private const val DEFAULT_LAST_NON_SILENT_VALUE = AudioManager.RINGER_MODE_NORMAL
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index ea6c107cd161..0d54ab9adb4a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -42,7 +42,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
- override val pickerName = context.getString(R.string.qr_code_scanner_title)
+ override fun pickerName(): String = context.getString(R.string.qr_code_scanner_title)
override val pickerIconResourceId = R.drawable.ic_qr_code_scanner
@@ -53,6 +53,7 @@ constructor(
override fun onQRCodeScannerActivityChanged() {
trySendWithFailureLogging(state(), TAG)
}
+
override fun onQRCodeScannerPreferenceChanged() {
trySendWithFailureLogging(state(), TAG)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 4ba2eb913742..44e74e7e339b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -18,7 +18,6 @@
package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context
-import android.content.Intent
import android.graphics.drawable.Drawable
import android.service.quickaccesswallet.GetWalletCardsError
import android.service.quickaccesswallet.GetWalletCardsResponse
@@ -33,7 +32,6 @@ import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.Companion.componentName
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.wallet.controller.QuickAccessWalletController
import javax.inject.Inject
@@ -53,7 +51,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
- override val pickerName: String = context.getString(R.string.accessibility_wallet_button)
+ override fun pickerName(): String = context.getString(R.string.accessibility_wallet_button)
override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
@@ -103,17 +101,6 @@ constructor(
!walletController.walletClient.isWalletServiceAvailable ->
KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
!walletController.isWalletEnabled || queryCards().isEmpty() -> {
- val componentName =
- walletController.walletClient.createWalletSettingsIntent().toComponentName()
- val actionText =
- if (componentName != null) {
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_action_template,
- pickerName,
- )
- } else {
- null
- }
KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
instructions =
listOf(
@@ -124,8 +111,6 @@ constructor(
R.string.keyguard_affordance_enablement_dialog_wallet_instruction_2
),
),
- actionText = actionText,
- actionComponentName = componentName,
)
}
else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
@@ -182,14 +167,6 @@ constructor(
}
}
- private fun Intent?.toComponentName(): String? {
- if (this == null) {
- return null
- }
-
- return componentName(packageName = `package`, action = action)
- }
-
companion object {
private const val TAG = "QuickAccessWalletKeyguardQuickAffordanceConfig"
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
index 6f821a2b5228..1ccc689da368 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
@@ -62,8 +62,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.VIDEO_CAMERA
- override val pickerName: String
- get() = context.getString(R.string.video_camera)
+ override fun pickerName(): String = context.getString(R.string.video_camera)
override val pickerIconResourceId: Int
get() = R.drawable.ic_videocam
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt
index 641e20b4a3fc..16ad29aeb734 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt
@@ -21,12 +21,17 @@ import android.provider.Settings
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import com.android.systemui.plugins.ClockId
+import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.withContext
@@ -35,6 +40,7 @@ class KeyguardClockRepository
@Inject
constructor(
private val secureSettings: SecureSettings,
+ private val clockRegistry: ClockRegistry,
@Background private val backgroundDispatcher: CoroutineDispatcher,
) {
@@ -47,6 +53,24 @@ constructor(
.onStart { emit(Unit) } // Forces an initial update.
.map { getClockSize() }
+ val currentClockId: Flow<ClockId> =
+ callbackFlow {
+ fun send() {
+ trySend(clockRegistry.currentClockId)
+ }
+
+ val listener =
+ object : ClockRegistry.ClockChangeListener {
+ override fun onCurrentClockChanged() {
+ send()
+ }
+ }
+ clockRegistry.registerClockChangeListener(listener)
+ send()
+ awaitClose { clockRegistry.unregisterClockChangeListener(listener) }
+ }
+ .mapNotNull { it }
+
private suspend fun getClockSize(): SettingsClockSize {
return withContext(backgroundDispatcher) {
if (
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index ab4abbf3d575..96c94d7d64b6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -170,7 +170,7 @@ constructor(
pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
KeyguardQuickAffordancePickerRepresentation(
id = config.key,
- name = config.pickerName,
+ name = config.pickerName(),
iconResourceId = config.pickerIconResourceId,
isEnabled =
pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.Default,
@@ -234,7 +234,9 @@ constructor(
pw.println(" $slotId$selectionText (capacity = $capacity)")
}
pw.println("Available affordances on device:")
- configs.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName}\")") }
+ configs.forEach { config ->
+ pw.println(" ${config.key} (\"${config.pickerName()}\")")
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index 742e53515e82..81f62b687e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -25,6 +25,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.Position
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
@@ -44,13 +45,16 @@ import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.stateIn
/** Defines interface for classes that encapsulate application state for the keyguard. */
interface KeyguardRepository {
@@ -138,7 +142,7 @@ interface KeyguardRepository {
val statusBarState: Flow<StatusBarState>
/** Observable for device wake/sleep state */
- val wakefulness: Flow<WakefulnessModel>
+ val wakefulness: StateFlow<WakefulnessModel>
/** Observable for biometric unlock modes */
val biometricUnlockState: Flow<BiometricUnlockModel>
@@ -202,7 +206,8 @@ constructor(
private val dozeParameters: DozeParameters,
private val authController: AuthController,
private val dreamOverlayCallbackController: DreamOverlayCallbackController,
- @Main private val mainDispatcher: CoroutineDispatcher
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Application private val scope: CoroutineScope,
) : KeyguardRepository {
private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
override val animateBottomAreaDozingTransitions =
@@ -486,47 +491,48 @@ constructor(
awaitClose { biometricUnlockController.removeListener(callback) }
}
- override val wakefulness: Flow<WakefulnessModel> = conflatedCallbackFlow {
- val observer =
- object : WakefulnessLifecycle.Observer {
- override fun onStartedWakingUp() {
- dispatchNewState()
- }
-
- override fun onFinishedWakingUp() {
- dispatchNewState()
- }
+ override val wakefulness: StateFlow<WakefulnessModel> =
+ conflatedCallbackFlow {
+ val observer =
+ object : WakefulnessLifecycle.Observer {
+ override fun onStartedWakingUp() {
+ dispatchNewState()
+ }
- override fun onPostFinishedWakingUp() {
- dispatchNewState()
- }
+ override fun onFinishedWakingUp() {
+ dispatchNewState()
+ }
- override fun onStartedGoingToSleep() {
- dispatchNewState()
- }
+ override fun onPostFinishedWakingUp() {
+ dispatchNewState()
+ }
- override fun onFinishedGoingToSleep() {
- dispatchNewState()
- }
+ override fun onStartedGoingToSleep() {
+ dispatchNewState()
+ }
- private fun dispatchNewState() {
- trySendWithFailureLogging(
- WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
- TAG,
- "updated wakefulness state"
- )
- }
- }
+ override fun onFinishedGoingToSleep() {
+ dispatchNewState()
+ }
- wakefulnessLifecycle.addObserver(observer)
- trySendWithFailureLogging(
- WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
- TAG,
- "initial wakefulness state"
- )
+ private fun dispatchNewState() {
+ trySendWithFailureLogging(
+ WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
+ TAG,
+ "updated wakefulness state",
+ )
+ }
+ }
- awaitClose { wakefulnessLifecycle.removeObserver(observer) }
- }
+ wakefulnessLifecycle.addObserver(observer)
+ awaitClose { wakefulnessLifecycle.removeObserver(observer) }
+ }
+ .stateIn(
+ scope,
+ // Use Eagerly so that we're always listening and never miss an event.
+ SharingStarted.Eagerly,
+ initialValue = WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
+ )
override val fingerprintSensorLocation: Flow<Point?> = conflatedCallbackFlow {
fun sendFpLocation() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
index 98f445c4419a..dad5831d6d4f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardClockRepository
import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import com.android.systemui.plugins.ClockId
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -31,4 +32,6 @@ constructor(
repository: KeyguardClockRepository,
) {
val selectedClockSize: Flow<SettingsClockSize> = repository.selectedClockSize
+
+ val currentClockId: Flow<ClockId> = repository.currentClockId
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 3cf9a9ec5a9c..d13d5ad67cae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -21,6 +21,7 @@ import android.app.StatusBarManager
import android.graphics.Point
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -39,6 +40,7 @@ import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
@@ -59,6 +61,7 @@ constructor(
private val commandQueue: CommandQueue,
featureFlags: FeatureFlags,
bouncerRepository: KeyguardBouncerRepository,
+ configurationRepository: ConfigurationRepository,
) {
/**
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -97,7 +100,7 @@ constructor(
}
/** The device wake/sleep state */
- val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
+ val wakefulnessModel: StateFlow<WakefulnessModel> = repository.wakefulness
/**
* Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
@@ -172,6 +175,9 @@ constructor(
/** The approximate location on the screen of the face unlock sensor, if one is available. */
val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation
+ /** Notifies when a new configuration is set */
+ val configurationChange: Flow<Unit> = configurationRepository.onAnyConfigurationChange
+
fun dozeTransitionTo(vararg states: DozeStateModel): Flow<DozeTransitionModel> {
return dozeTransitionModel.filter { states.contains(it.to) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
index 51ce7ff45182..fb685dab1797 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt
@@ -23,9 +23,12 @@ enum class WakeSleepReason {
/** The physical power button was pressed to wake up or sleep the device. */
POWER_BUTTON,
- /** The user has taped or double tapped to wake the screen */
+ /** The user has tapped or double tapped to wake the screen. */
TAP,
+ /** The user performed some sort of gesture to wake the screen. */
+ GESTURE,
+
/** Something else happened to wake up or sleep the device. */
OTHER;
@@ -34,6 +37,7 @@ enum class WakeSleepReason {
return when (reason) {
PowerManager.WAKE_REASON_POWER_BUTTON -> POWER_BUTTON
PowerManager.WAKE_REASON_TAP -> TAP
+ PowerManager.WAKE_REASON_GESTURE -> GESTURE
else -> OTHER
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakefulnessModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakefulnessModel.kt
index 7ca90ba63fda..dd577137599a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakefulnessModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakefulnessModel.kt
@@ -27,7 +27,11 @@ data class WakefulnessModel(
fun isStartingToSleep() = state == WakefulnessState.STARTING_TO_SLEEP
- fun isStartingToSleepOrAsleep() = isStartingToSleep() || state == WakefulnessState.ASLEEP
+ private fun isAsleep() = state == WakefulnessState.ASLEEP
+
+ fun isStartingToSleepOrAsleep() = isStartingToSleep() || isAsleep()
+
+ fun isDeviceInteractive() = !isAsleep()
fun isStartingToSleepFromPowerButton() =
isStartingToSleep() && lastWakeReason == WakeSleepReason.POWER_BUTTON
@@ -41,6 +45,11 @@ data class WakefulnessModel(
fun isAwakeFromTap() =
state == WakefulnessState.STARTING_TO_WAKE && lastWakeReason == WakeSleepReason.TAP
+ fun isDeviceInteractiveFromTapOrGesture(): Boolean {
+ return isDeviceInteractive() &&
+ (lastWakeReason == WakeSleepReason.TAP || lastWakeReason == WakeSleepReason.GESTURE)
+ }
+
companion object {
fun fromWakefulnessLifecycle(wakefulnessLifecycle: WakefulnessLifecycle): WakefulnessModel {
return WakefulnessModel(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index c8d37a165a0e..7d14198bdb17 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -21,12 +21,10 @@ import android.content.Intent
import android.graphics.Rect
import android.graphics.drawable.Animatable2
import android.util.Size
-import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.ViewPropertyAnimator
import android.widget.ImageView
-import android.widget.TextView
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
@@ -108,14 +106,10 @@ object KeyguardBottomAreaViewBinder {
activityStarter: ActivityStarter?,
messageDisplayer: (Int) -> Unit,
): Binding {
- val indicationArea: View = view.requireViewById(R.id.keyguard_indication_area)
val ambientIndicationArea: View? = view.findViewById(R.id.ambient_indication_container)
val startButton: ImageView = view.requireViewById(R.id.start_button)
val endButton: ImageView = view.requireViewById(R.id.end_button)
val overlayContainer: View = view.requireViewById(R.id.overlay_container)
- val indicationText: TextView = view.requireViewById(R.id.keyguard_indication_text)
- val indicationTextBottom: TextView =
- view.requireViewById(R.id.keyguard_indication_text_bottom)
val settingsMenu: LaunchableLinearLayout =
view.requireViewById(R.id.keyguard_settings_button)
@@ -183,7 +177,6 @@ object KeyguardBottomAreaViewBinder {
}
ambientIndicationArea?.alpha = alpha
- indicationArea.alpha = alpha
}
}
@@ -205,50 +198,23 @@ object KeyguardBottomAreaViewBinder {
launch {
viewModel.indicationAreaTranslationX.collect { translationX ->
- indicationArea.translationX = translationX
ambientIndicationArea?.translationX = translationX
}
}
launch {
- combine(
- viewModel.isIndicationAreaPadded,
- configurationBasedDimensions.map { it.indicationAreaPaddingPx },
- ) { isPadded, paddingIfPaddedPx ->
- if (isPadded) {
- paddingIfPaddedPx
- } else {
- 0
- }
- }
- .collect { paddingPx ->
- indicationArea.setPadding(paddingPx, 0, paddingPx, 0)
- }
- }
-
- launch {
configurationBasedDimensions
.map { it.defaultBurnInPreventionYOffsetPx }
.flatMapLatest { defaultBurnInOffsetY ->
viewModel.indicationAreaTranslationY(defaultBurnInOffsetY)
}
.collect { translationY ->
- indicationArea.translationY = translationY
ambientIndicationArea?.translationY = translationY
}
}
launch {
configurationBasedDimensions.collect { dimensions ->
- indicationText.setTextSize(
- TypedValue.COMPLEX_UNIT_PX,
- dimensions.indicationTextSizePx.toFloat(),
- )
- indicationTextBottom.setTextSize(
- TypedValue.COMPLEX_UNIT_PX,
- dimensions.indicationTextSizePx.toFloat(),
- )
-
startButton.updateLayoutParams<ViewGroup.LayoutParams> {
width = dimensions.buttonSizePx.width
height = dimensions.buttonSizePx.height
@@ -305,7 +271,7 @@ object KeyguardBottomAreaViewBinder {
return object : Binding {
override fun getIndicationAreaAnimators(): List<ViewPropertyAnimator> {
- return listOf(indicationArea, ambientIndicationArea).mapNotNull { it?.animate() }
+ return listOf(ambientIndicationArea).mapNotNull { it?.animate() }
}
override fun onConfigurationChanged() {
@@ -406,19 +372,21 @@ object KeyguardBottomAreaViewBinder {
view.isClickable = viewModel.isClickable
if (viewModel.isClickable) {
if (viewModel.useLongPress) {
- view.setOnTouchListener(
- KeyguardQuickAffordanceOnTouchListener(
- view,
- viewModel,
- messageDisplayer,
- vibratorHelper,
- falsingManager,
- )
+ val onTouchListener = KeyguardQuickAffordanceOnTouchListener(
+ view,
+ viewModel,
+ messageDisplayer,
+ vibratorHelper,
+ falsingManager,
)
+ view.setOnTouchListener(onTouchListener)
+ view.onLongClickListener =
+ OnLongClickListener(falsingManager, viewModel, vibratorHelper, onTouchListener)
} else {
view.setOnClickListener(OnClickListener(viewModel, checkNotNull(falsingManager)))
}
} else {
+ view.onLongClickListener = null
view.setOnClickListener(null)
view.setOnTouchListener(null)
}
@@ -454,6 +422,42 @@ object KeyguardBottomAreaViewBinder {
.start()
}
+ private class OnLongClickListener(
+ private val falsingManager: FalsingManager?,
+ private val viewModel: KeyguardQuickAffordanceViewModel,
+ private val vibratorHelper: VibratorHelper?,
+ private val onTouchListener: KeyguardQuickAffordanceOnTouchListener
+ ) : View.OnLongClickListener {
+ override fun onLongClick(view: View): Boolean {
+ if (falsingManager?.isFalseLongTap(FalsingManager.MODERATE_PENALTY) == true) {
+ return true
+ }
+
+ if (viewModel.configKey != null) {
+ viewModel.onClicked(
+ KeyguardQuickAffordanceViewModel.OnClickedParameters(
+ configKey = viewModel.configKey,
+ expandable = Expandable.fromView(view),
+ slotId = viewModel.slotId,
+ )
+ )
+ vibratorHelper?.vibrate(
+ if (viewModel.isActivated) {
+ KeyguardBottomAreaVibrations.Activated
+ } else {
+ KeyguardBottomAreaVibrations.Deactivated
+ }
+ )
+ }
+
+ onTouchListener.cancel()
+ return true
+ }
+
+ override fun onLongClickUseDefaultHapticFeedback(view: View?) = false
+
+ }
+
private class OnClickListener(
private val viewModel: KeyguardQuickAffordanceViewModel,
private val falsingManager: FalsingManager,
@@ -479,12 +483,6 @@ object KeyguardBottomAreaViewBinder {
return ConfigurationBasedDimensions(
defaultBurnInPreventionYOffsetPx =
view.resources.getDimensionPixelOffset(R.dimen.default_burn_in_prevention_offset),
- indicationAreaPaddingPx =
- view.resources.getDimensionPixelOffset(R.dimen.keyguard_indication_area_padding),
- indicationTextSizePx =
- view.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.text_size_small_material,
- ),
buttonSizePx =
Size(
view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
@@ -514,8 +512,6 @@ object KeyguardBottomAreaViewBinder {
private data class ConfigurationBasedDimensions(
val defaultBurnInPreventionYOffsetPx: Int,
- val indicationAreaPaddingPx: Int,
- val indicationTextSizePx: Int,
val buttonSizePx: Size,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
new file mode 100644
index 000000000000..02e6765fa1d3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.binder
+
+import android.util.TypedValue
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.R
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.KeyguardIndicationController
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Binds a keyguard indication area view to its view-model.
+ *
+ * To use this properly, users should maintain a one-to-one relationship between the [View] and the
+ * view-binding, binding each view only once. It is okay and expected for the same instance of the
+ * view-model to be reused for multiple view/view-binder bindings.
+ */
+@OptIn(ExperimentalCoroutinesApi::class)
+object KeyguardIndicationAreaBinder {
+
+ /** Binds the view to the view-model, continuing to update the former based on the latter. */
+ @JvmStatic
+ fun bind(
+ view: ViewGroup,
+ viewModel: KeyguardIndicationAreaViewModel,
+ indicationController: KeyguardIndicationController,
+ ): DisposableHandle {
+ val indicationArea: ViewGroup = view.requireViewById(R.id.keyguard_indication_area)
+ indicationController.setIndicationArea(indicationArea)
+
+ val indicationText: TextView = indicationArea.requireViewById(R.id.keyguard_indication_text)
+ val indicationTextBottom: TextView =
+ indicationArea.requireViewById(R.id.keyguard_indication_text_bottom)
+
+ view.clipChildren = false
+ view.clipToPadding = false
+
+ val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
+ val disposableHandle =
+ view.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.alpha.collect { alpha ->
+ view.importantForAccessibility =
+ if (alpha == 0f) {
+ View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+ } else {
+ View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
+ }
+
+ indicationArea.alpha = alpha
+ }
+ }
+
+ launch {
+ viewModel.indicationAreaTranslationX.collect { translationX ->
+ indicationArea.translationX = translationX
+ }
+ }
+
+ launch {
+ combine(
+ viewModel.isIndicationAreaPadded,
+ configurationBasedDimensions.map { it.indicationAreaPaddingPx },
+ ) { isPadded, paddingIfPaddedPx ->
+ if (isPadded) {
+ paddingIfPaddedPx
+ } else {
+ 0
+ }
+ }
+ .collect { paddingPx ->
+ indicationArea.setPadding(paddingPx, 0, paddingPx, 0)
+ }
+ }
+
+ launch {
+ configurationBasedDimensions
+ .map { it.defaultBurnInPreventionYOffsetPx }
+ .flatMapLatest { defaultBurnInOffsetY ->
+ viewModel.indicationAreaTranslationY(defaultBurnInOffsetY)
+ }
+ .collect { translationY -> indicationArea.translationY = translationY }
+ }
+
+ launch {
+ configurationBasedDimensions.collect { dimensions ->
+ indicationText.setTextSize(
+ TypedValue.COMPLEX_UNIT_PX,
+ dimensions.indicationTextSizePx.toFloat(),
+ )
+ indicationTextBottom.setTextSize(
+ TypedValue.COMPLEX_UNIT_PX,
+ dimensions.indicationTextSizePx.toFloat(),
+ )
+ }
+ }
+
+ launch {
+ viewModel.configurationChange.collect {
+ configurationBasedDimensions.value = loadFromResources(view)
+ }
+ }
+ }
+ }
+ return disposableHandle
+ }
+
+ private fun loadFromResources(view: View): ConfigurationBasedDimensions {
+ return ConfigurationBasedDimensions(
+ defaultBurnInPreventionYOffsetPx =
+ view.resources.getDimensionPixelOffset(R.dimen.default_burn_in_prevention_offset),
+ indicationAreaPaddingPx =
+ view.resources.getDimensionPixelOffset(R.dimen.keyguard_indication_area_padding),
+ indicationTextSizePx =
+ view.resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.text_size_small_material,
+ ),
+ )
+ }
+
+ private data class ConfigurationBasedDimensions(
+ val defaultBurnInPreventionYOffsetPx: Int,
+ val indicationAreaPaddingPx: Int,
+ val indicationTextSizePx: Int,
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 57c32b3a56d9..1b5b329f3f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -21,19 +21,17 @@ import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockSmartspaceViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
-import kotlinx.coroutines.flow.collect
-/** Binder for the small clock view, large clock view and smartspace. */
-object KeyguardPreviewClockSmartspaceViewBinder {
+/** Binder for the small clock view, large clock view. */
+object KeyguardPreviewClockViewBinder {
@JvmStatic
fun bind(
largeClockHostView: View,
smallClockHostView: View,
- smartspace: View?,
- viewModel: KeyguardPreviewClockSmartspaceViewModel,
+ viewModel: KeyguardPreviewClockViewModel,
) {
largeClockHostView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -46,15 +44,5 @@ object KeyguardPreviewClockSmartspaceViewBinder {
viewModel.isSmallClockVisible.collect { smallClockHostView.isVisible = it }
}
}
-
- smartspace?.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- viewModel.smartSpaceTopPadding.collect { smartspace.setTopPadding(it) }
- }
- }
- }
-
- private fun View.setTopPadding(padding: Int) {
- setPaddingRelative(paddingStart, padding, paddingEnd, paddingBottom)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
new file mode 100644
index 000000000000..f5e4c6adcb91
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.binder
+
+import android.view.View
+import androidx.core.view.isInvisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.launch
+
+/** Binder for the small clock view, large clock view and smartspace. */
+object KeyguardPreviewSmartspaceViewBinder {
+
+ @JvmStatic
+ fun bind(
+ smartspace: View,
+ viewModel: KeyguardPreviewSmartspaceViewModel,
+ ) {
+ smartspace.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch { viewModel.smartspaceTopPadding.collect { smartspace.setTopPadding(it) } }
+
+ launch { viewModel.shouldHideSmartspace.collect { smartspace.isInvisible = it } }
+ }
+ }
+ }
+
+ private fun View.setTopPadding(padding: Int) {
+ setPaddingRelative(paddingStart, padding, paddingEnd, paddingBottom)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
index 5745d6ae077e..7685345805f4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
@@ -46,7 +46,7 @@ class KeyguardQuickAffordanceOnTouchListener(
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent): Boolean {
return when (event.actionMasked) {
- MotionEvent.ACTION_DOWN ->
+ MotionEvent.ACTION_DOWN -> {
if (viewModel.configKey != null) {
downDisplayCoords.set(event.rawX, event.rawY)
if (isUsingAccurateTool(event)) {
@@ -62,21 +62,10 @@ class KeyguardQuickAffordanceOnTouchListener(
.scaleX(PRESSED_SCALE)
.scaleY(PRESSED_SCALE)
.setDuration(longPressDurationMs)
- .withEndAction {
- if (
- falsingManager?.isFalseLongTap(
- FalsingManager.MODERATE_PENALTY
- ) == false
- ) {
- dispatchClick(viewModel.configKey)
- }
- cancel()
- }
}
- true
- } else {
- false
}
+ false
+ }
MotionEvent.ACTION_MOVE -> {
if (!isUsingAccurateTool(event)) {
// Moving too far while performing a long-press gesture cancels that
@@ -91,7 +80,7 @@ class KeyguardQuickAffordanceOnTouchListener(
cancel()
}
}
- true
+ false
}
MotionEvent.ACTION_UP -> {
if (isUsingAccurateTool(event)) {
@@ -146,7 +135,7 @@ class KeyguardQuickAffordanceOnTouchListener(
}
)
}
- true
+ false
}
MotionEvent.ACTION_CANCEL -> {
cancel()
@@ -179,7 +168,7 @@ class KeyguardQuickAffordanceOnTouchListener(
view.setOnClickListener(null)
}
- private fun cancel(onAnimationEnd: Runnable? = null) {
+ fun cancel(onAnimationEnd: Runnable? = null) {
longPressAnimator?.cancel()
longPressAnimator = null
view.animate().scaleX(1f).scaleY(1f).withEndAction(onAnimationEnd)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 4308d843c27a..db231092d7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -17,7 +17,7 @@
package com.android.systemui.keyguard.ui.preview
-import android.annotation.ColorInt
+import android.app.WallpaperColors
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -42,9 +42,12 @@ import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockSmartspaceViewBinder
+import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockViewBinder
+import com.android.systemui.keyguard.ui.binder.KeyguardPreviewSmartspaceViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockSmartspaceViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
+import com.android.systemui.monet.ColorScheme
import com.android.systemui.plugins.ClockController
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.shared.clocks.DefaultClockController
@@ -65,7 +68,8 @@ constructor(
@Application private val context: Context,
@Main private val mainDispatcher: CoroutineDispatcher,
@Main private val mainHandler: Handler,
- private val clockSmartspaceViewModel: KeyguardPreviewClockSmartspaceViewModel,
+ private val clockViewModel: KeyguardPreviewClockViewModel,
+ private val smartspaceViewModel: KeyguardPreviewSmartspaceViewModel,
private val bottomAreaViewModel: KeyguardBottomAreaViewModel,
displayManager: DisplayManager,
private val windowManager: WindowManager,
@@ -88,6 +92,7 @@ constructor(
/** [shouldHideClock] here means that we never create and bind the clock views */
private val shouldHideClock: Boolean =
bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false)
+ private val wallpaperColors: WallpaperColors? = bundle.getParcelable(KEY_COLORS)
private var host: SurfaceControlViewHost
@@ -97,7 +102,6 @@ constructor(
private lateinit var largeClockHostView: FrameLayout
private lateinit var smallClockHostView: FrameLayout
private var smartSpaceView: View? = null
- private var colorOverride: Int? = null
private val disposables = mutableSetOf<DisposableHandle>()
private var isDestroyed = false
@@ -129,16 +133,18 @@ constructor(
setUpBottomArea(rootView)
setUpSmartspace(rootView)
+ smartSpaceView?.let {
+ KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel)
+ }
setUpUdfps(rootView)
if (!shouldHideClock) {
setUpClock(rootView)
- KeyguardPreviewClockSmartspaceViewBinder.bind(
+ KeyguardPreviewClockViewBinder.bind(
largeClockHostView,
smallClockHostView,
- smartSpaceView,
- clockSmartspaceViewModel,
+ clockViewModel,
)
}
@@ -167,6 +173,10 @@ constructor(
rootView.translationX = (width - scale * rootView.width) / 2
rootView.translationY = (height - scale * rootView.height) / 2
+ if (isDestroyed) {
+ return@post
+ }
+
host.setView(rootView, rootView.measuredWidth, rootView.measuredHeight)
}
}
@@ -190,14 +200,6 @@ constructor(
mainHandler.post { smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE }
}
- /** Sets the clock's color to the overridden seed color. */
- fun onColorOverridden(@ColorInt color: Int?) {
- mainHandler.post {
- colorOverride = color
- clockController.clock?.run { events.onSeedColorChanged(color) }
- }
- }
-
/**
* This sets up and shows a non-interactive smart space
*
@@ -219,8 +221,8 @@ constructor(
smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
val topPadding: Int =
- KeyguardPreviewClockSmartspaceViewModel.getLargeClockSmartspaceTopPadding(
- context.resources
+ KeyguardPreviewSmartspaceViewModel.getLargeClockSmartspaceTopPadding(
+ context.resources,
)
val startPadding: Int =
@@ -235,7 +237,7 @@ constructor(
smartSpaceView?.let {
it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
it.isClickable = false
-
+ it.isInvisible = true
parentView.addView(
it,
FrameLayout.LayoutParams(
@@ -372,7 +374,7 @@ constructor(
resources.getDimensionPixelSize(R.dimen.small_clock_height)
)
layoutParams.topMargin =
- KeyguardPreviewClockSmartspaceViewModel.getStatusBarHeight(resources) +
+ KeyguardPreviewSmartspaceViewModel.getStatusBarHeight(resources) +
resources.getDimensionPixelSize(R.dimen.small_clock_padding_top)
hostView.layoutParams = layoutParams
@@ -390,13 +392,27 @@ constructor(
val clock = clockRegistry.createCurrentClock()
clockController.clock = clock
- colorOverride?.let { clock.events.onSeedColorChanged(it) }
+ if (clockRegistry.seedColor == null) {
+ // Seed color null means users do override any color on the clock. The default color
+ // will need to use wallpaper's extracted color and consider if the wallpaper's color
+ // is dark or a light.
+ // TODO(b/277832214) we can potentially simplify this code by checking for
+ // wallpaperColors being null in the if clause above and removing the many ?.
+ val wallpaperColorScheme =
+ wallpaperColors?.let { ColorScheme(it, /* darkTheme= */ false) }
+ val lightClockColor = wallpaperColorScheme?.accent1?.s100
+ val darkClockColor = wallpaperColorScheme?.accent2?.s600
+ /** Note that when [wallpaperColors] is null, isWallpaperDark is true. */
+ val isWallpaperDark: Boolean =
+ (wallpaperColors?.colorHints?.and(WallpaperColors.HINT_SUPPORTS_DARK_TEXT)) !=
+ WallpaperColors.HINT_SUPPORTS_DARK_TEXT
+ clock.events.onSeedColorChanged(
+ if (isWallpaperDark) lightClockColor else darkClockColor
+ )
+ }
updateLargeClock(clock)
updateSmallClock(clock)
-
- // Hide smart space if the clock has weather display; otherwise show it
- hideSmartspace(clock.largeClock.config.hasCustomWeatherDataDisplay)
}
private fun updateLargeClock(clock: ClockController) {
@@ -426,6 +442,7 @@ constructor(
private const val KEY_VIEW_WIDTH = "width"
private const val KEY_VIEW_HEIGHT = "height"
private const val KEY_DISPLAY_ID = "display_id"
+ private const val KEY_COLORS = "wallpaper_colors"
private const val DIM_ALPHA = 0.3f
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
index 79712f9c6be5..dafeacef60bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -124,13 +124,6 @@ constructor(
message.data.getBoolean(KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE)
)
}
- KeyguardPreviewConstants.MESSAGE_ID_COLOR_OVERRIDE -> {
- renderer.onColorOverridden(
- message.data
- .getString(KeyguardPreviewConstants.KEY_COLOR_OVERRIDE)
- ?.toIntOrNull()
- )
- }
else -> requestDestruction(this)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt
new file mode 100644
index 000000000000..890d565b03a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.view
+
+import android.content.Context
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.View
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.LinearLayout
+import com.android.systemui.R
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+
+class KeyguardIndicationArea(
+ context: Context,
+ private val attrs: AttributeSet?,
+) :
+ LinearLayout(
+ context,
+ attrs,
+ ) {
+
+ init {
+ setId(R.id.keyguard_indication_area)
+ orientation = LinearLayout.VERTICAL
+
+ addView(indicationTopRow(), LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
+ addView(
+ indicationBottomRow(),
+ LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
+ gravity = Gravity.CENTER_HORIZONTAL
+ }
+ )
+ }
+
+ private fun indicationTopRow(): KeyguardIndicationTextView {
+ return KeyguardIndicationTextView(context, attrs).apply {
+ id = R.id.keyguard_indication_text
+ gravity = Gravity.CENTER
+ accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
+ setTextAppearance(R.style.TextAppearance_Keyguard_BottomArea)
+
+ val padding = R.dimen.keyguard_indication_text_padding.dp()
+ setPaddingRelative(padding, 0, padding, 0)
+ }
+ }
+
+ private fun indicationBottomRow(): KeyguardIndicationTextView {
+ return KeyguardIndicationTextView(context, attrs).apply {
+ id = R.id.keyguard_indication_text_bottom
+ gravity = Gravity.CENTER
+ accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
+
+ setTextAppearance(R.style.TextAppearance_Keyguard_BottomArea)
+ setEllipsize(TextUtils.TruncateAt.END)
+ setAlpha(0.8f)
+ setMinHeight(R.dimen.keyguard_indication_text_min_height.dp())
+ setMaxLines(2)
+ setVisibility(View.GONE)
+
+ val padding = R.dimen.keyguard_indication_text_padding.dp()
+ setPaddingRelative(padding, 0, padding, 0)
+ }
+ }
+
+ private fun Int.dp(): Int {
+ return context.resources.getDimensionPixelSize(this)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
new file mode 100644
index 000000000000..abf0e80bd87a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.FrameLayout
+import com.android.systemui.R
+
+/** Provides a container for all keyguard ui content. */
+class KeyguardRootView(
+ context: Context,
+ private val attrs: AttributeSet?,
+) :
+ FrameLayout(
+ context,
+ attrs,
+ ) {
+
+ init {
+ addIndicationTextArea()
+ }
+
+ private fun addIndicationTextArea() {
+ val view = KeyguardIndicationArea(context, attrs)
+ addView(
+ view,
+ FrameLayout.LayoutParams(
+ MATCH_PARENT,
+ WRAP_CONTENT,
+ )
+ .apply {
+ gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
+ bottomMargin = R.dimen.keyguard_indication_margin_bottom.dp()
+ }
+ )
+ }
+
+ private fun Int.dp(): Int {
+ return context.resources.getDimensionPixelSize(this)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 62a1a9e16fc6..3e6f8e68891a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -57,7 +57,7 @@ constructor(
* in the wallpaper picker application. This should _always_ be `false` for the real lock screen
* experience.
*/
- private val previewMode = MutableStateFlow(PreviewMode())
+ val previewMode = MutableStateFlow(PreviewMode())
/**
* ID of the slot that's currently selected in the preview that renders exclusively in the
@@ -101,12 +101,6 @@ constructor(
bottomAreaInteractor.alpha.distinctUntilChanged()
}
}
- /** An observable for whether the indication area should be padded. */
- val isIndicationAreaPadded: Flow<Boolean> =
- combine(startButton, endButton) { startButtonModel, endButtonModel ->
- startButtonModel.isVisible || endButtonModel.isVisible
- }
- .distinctUntilChanged()
/** An observable for the x-offset by which the indication area should be translated. */
val indicationAreaTranslationX: Flow<Float> =
bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
new file mode 100644
index 000000000000..389cf76c47ac
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.doze.util.BurnInHelperWrapper
+import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+/** View-model for the keyguard indication area view */
+@OptIn(ExperimentalCoroutinesApi::class)
+class KeyguardIndicationAreaViewModel
+@Inject
+constructor(
+ private val keyguardInteractor: KeyguardInteractor,
+ private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
+ private val keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel,
+ private val burnInHelperWrapper: BurnInHelperWrapper,
+) {
+
+ /** Notifies when a new configuration is set */
+ val configurationChange: Flow<Unit> = keyguardInteractor.configurationChange
+
+ /** An observable for the alpha level for the entire bottom area. */
+ val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha
+
+ /** An observable for whether the indication area should be padded. */
+ val isIndicationAreaPadded: Flow<Boolean> =
+ combine(keyguardBottomAreaViewModel.startButton, keyguardBottomAreaViewModel.endButton) {
+ startButtonModel,
+ endButtonModel ->
+ startButtonModel.isVisible || endButtonModel.isVisible
+ }
+ .distinctUntilChanged()
+ /** An observable for the x-offset by which the indication area should be translated. */
+ val indicationAreaTranslationX: Flow<Float> =
+ bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
+
+ /** Returns an observable for the y-offset by which the indication area should be translated. */
+ fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
+ return keyguardInteractor.dozeAmount
+ .map { dozeAmount ->
+ dozeAmount *
+ (burnInHelperWrapper.burnInOffset(
+ /* amplitude = */ defaultBurnInOffset * 2,
+ /* xAxis= */ false,
+ ) - defaultBurnInOffset)
+ }
+ .distinctUntilChanged()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt
new file mode 100644
index 000000000000..53013026670c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import android.content.Context
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+/** View model for the small clock view, large clock view. */
+class KeyguardPreviewClockViewModel
+@Inject
+constructor(
+ @Application private val context: Context,
+ interactor: KeyguardClockInteractor,
+) {
+
+ val isLargeClockVisible: Flow<Boolean> =
+ interactor.selectedClockSize.map { it == SettingsClockSize.DYNAMIC }
+
+ val isSmallClockVisible: Flow<Boolean> =
+ interactor.selectedClockSize.map { it == SettingsClockSize.SMALL }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 00c603b04ccf..bf51976e27f0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -24,23 +24,18 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.shared.model.SettingsClockSize
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
-/** View model for the small clock view, large clock view and smartspace. */
-class KeyguardPreviewClockSmartspaceViewModel
+/** View model for the smartspace. */
+class KeyguardPreviewSmartspaceViewModel
@Inject
constructor(
@Application private val context: Context,
interactor: KeyguardClockInteractor,
) {
- val isLargeClockVisible: Flow<Boolean> =
- interactor.selectedClockSize.map { it == SettingsClockSize.DYNAMIC }
-
- val isSmallClockVisible: Flow<Boolean> =
- interactor.selectedClockSize.map { it == SettingsClockSize.SMALL }
-
- val smartSpaceTopPadding: Flow<Int> =
+ val smartspaceTopPadding: Flow<Int> =
interactor.selectedClockSize.map {
when (it) {
SettingsClockSize.DYNAMIC -> getLargeClockSmartspaceTopPadding(context.resources)
@@ -48,6 +43,22 @@ constructor(
}
}
+ val shouldHideSmartspace: Flow<Boolean> =
+ combine(
+ interactor.selectedClockSize,
+ interactor.currentClockId,
+ ::Pair,
+ )
+ .map { (size, currentClockId) ->
+ when (size) {
+ // TODO (b/284122375) This is temporary. We should use clockController
+ // .largeClock.config.hasCustomWeatherDataDisplay instead, but
+ // ClockRegistry.createCurrentClock is not reliable.
+ SettingsClockSize.DYNAMIC -> currentClockId == "DIGITAL_CLOCK_WEATHER"
+ SettingsClockSize.SMALL -> false
+ }
+ }
+
companion object {
fun getLargeClockSmartspaceTopPadding(resources: Resources): Int {
return with(resources) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index c9c2ea27e5f4..f6a2f3704283 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -29,6 +29,7 @@ import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -203,14 +204,17 @@ public class MediaProjectionPermissionActivity extends Activity
dialogTitle = getString(R.string.media_projection_dialog_title, appName);
}
+ // Using application context for the dialog, instead of the activity context, so we get
+ // the correct screen width when in split screen.
+ Context dialogContext = getApplicationContext();
if (isPartialScreenSharingEnabled()) {
- mDialog = new MediaProjectionPermissionDialog(this, () -> {
+ mDialog = new MediaProjectionPermissionDialog(dialogContext, () -> {
ScreenShareOption selectedOption =
((MediaProjectionPermissionDialog) mDialog).getSelectedScreenShareOption();
grantMediaProjectionPermission(selectedOption.getMode());
}, () -> finish(RECORD_CANCEL, /* projection= */ null), appName);
} else {
- AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this,
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(dialogContext,
R.style.Theme_SystemUI_Dialog)
.setTitle(dialogTitle)
.setIcon(R.drawable.ic_media_projection_permission)
@@ -263,7 +267,10 @@ public class MediaProjectionPermissionActivity extends Activity
final UserHandle hostUserHandle = getHostUserHandle();
if (mScreenCaptureDevicePolicyResolver.get()
.isScreenCaptureCompletelyDisabled(hostUserHandle)) {
- AlertDialog dialog = new ScreenCaptureDisabledDialog(this);
+ // Using application context for the dialog, instead of the activity context, so we get
+ // the correct screen width when in split screen.
+ Context dialogContext = getApplicationContext();
+ AlertDialog dialog = new ScreenCaptureDisabledDialog(dialogContext);
setUpDialog(dialog);
dialog.show();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
index e38abc2228c4..6eaff3fcb929 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt
@@ -56,6 +56,7 @@ open class SeekBarObserver(private val holder: MediaViewHolder) :
R.dimen.qs_media_session_disabled_seekbar_vertical_padding
)
var seekBarResetAnimator: Animator? = null
+ var animationEnabled: Boolean = true
init {
val seekBarProgressWavelength =
@@ -104,7 +105,7 @@ open class SeekBarObserver(private val holder: MediaViewHolder) :
holder.seekBar.thumb.alpha = if (data.seekAvailable) 255 else 0
holder.seekBar.isEnabled = data.seekAvailable
- progressDrawable?.animate = data.playing && !data.scrubbing
+ progressDrawable?.animate = data.playing && !data.scrubbing && animationEnabled
progressDrawable?.transitionEnabled = !data.seekAvailable
if (holder.seekBar.maxHeight != seekBarEnabledMaxHeight) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index 1469d96dd3e8..6b993ce9e7bf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -16,10 +16,12 @@
package com.android.systemui.media.controls.pipeline
+import android.annotation.SuppressLint
import android.app.BroadcastOptions
import android.app.Notification
import android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME
import android.app.PendingIntent
+import android.app.StatusBarManager
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
import android.app.smartspace.SmartspaceSession
@@ -43,7 +45,6 @@ import android.media.session.PlaybackState
import android.net.Uri
import android.os.Parcelable
import android.os.Process
-import android.os.RemoteException
import android.os.UserHandle
import android.provider.Settings
import android.service.notification.StatusBarNotification
@@ -52,8 +53,8 @@ import android.text.TextUtils
import android.util.Log
import android.util.Pair as APair
import androidx.media.utils.MediaConstants
+import com.android.internal.annotations.Keep
import com.android.internal.logging.InstanceId
-import com.android.internal.statusbar.IStatusBarService
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.Dumpable
import com.android.systemui.R
@@ -185,7 +186,6 @@ class MediaDataManager(
private val logger: MediaUiEventLogger,
private val smartspaceManager: SmartspaceManager,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
- private val statusBarService: IStatusBarService,
) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
companion object {
@@ -220,7 +220,7 @@ class MediaDataManager(
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
// There should ONLY be at most one Smartspace media recommendation.
var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
- private var smartspaceSession: SmartspaceSession? = null
+ @Keep private var smartspaceSession: SmartspaceSession? = null
private var allowMediaRecommendations = allowMediaRecommendations(context)
private val artworkWidth =
@@ -230,6 +230,10 @@ class MediaDataManager(
private val artworkHeight =
context.resources.getDimensionPixelSize(R.dimen.qs_media_session_height_expanded)
+ @SuppressLint("WrongConstant") // sysui allowed to call STATUS_BAR_SERVICE
+ private val statusBarManager =
+ context.getSystemService(Context.STATUS_BAR_SERVICE) as StatusBarManager
+
/** Check whether this notification is an RCN */
private fun isRemoteCastNotification(sbn: StatusBarNotification): Boolean {
return sbn.notification.extras.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE)
@@ -257,7 +261,6 @@ class MediaDataManager(
mediaFlags: MediaFlags,
logger: MediaUiEventLogger,
smartspaceManager: SmartspaceManager,
- statusBarService: IStatusBarService,
keyguardUpdateMonitor: KeyguardUpdateMonitor,
) : this(
context,
@@ -283,7 +286,6 @@ class MediaDataManager(
logger,
smartspaceManager,
keyguardUpdateMonitor,
- statusBarService,
)
private val appChangeReceiver =
@@ -380,6 +382,8 @@ class MediaDataManager(
fun destroy() {
smartspaceMediaDataProvider.unregisterListener(this)
+ smartspaceSession?.close()
+ smartspaceSession = null
context.unregisterReceiver(appChangeReceiver)
}
@@ -793,27 +797,12 @@ class MediaDataManager(
song = HybridGroupManager.resolveTitle(notif)
}
if (song.isNullOrBlank()) {
- if (mediaFlags.isMediaTitleRequired(sbn.packageName, sbn.user)) {
- // App is required to provide a title: cancel the underlying notification
- try {
- statusBarService.onNotificationError(
- sbn.packageName,
- sbn.tag,
- sbn.id,
- sbn.uid,
- sbn.initialPid,
- MEDIA_TITLE_ERROR_MESSAGE,
- sbn.user.identifier
- )
- } catch (e: RemoteException) {
- Log.e(TAG, "cancelNotification failed: $e")
- }
- // Only add log for media removed if active media is updated with invalid title.
- foregroundExecutor.execute { removeEntry(key, !isNewlyActiveEntry) }
- return
- } else {
- // For apps that don't have the title requirement yet, add a placeholder
- song = context.getString(R.string.controls_media_empty_title, appName)
+ // For apps that don't include a title, log and add a placeholder
+ song = context.getString(R.string.controls_media_empty_title, appName)
+ try {
+ statusBarManager.logBlankMediaTitle(sbn.packageName, sbn.user.identifier)
+ } catch (e: RuntimeException) {
+ Log.e(TAG, "Error reporting blank media title for package ${sbn.packageName}")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 32a793556681..516fbf5ca12c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -34,6 +34,7 @@ import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
@@ -54,6 +55,7 @@ import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Process;
import android.os.Trace;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -121,6 +123,7 @@ import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseContro
import com.android.systemui.util.ColorUtilKt;
import com.android.systemui.util.animation.TransitionLayout;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.time.SystemClock;
import dagger.Lazy;
@@ -244,11 +247,19 @@ public class MediaControlPanel {
private MultiRippleController mMultiRippleController;
private TurbulenceNoiseController mTurbulenceNoiseController;
private final FeatureFlags mFeatureFlags;
+ private final GlobalSettings mGlobalSettings;
// TODO(b/281032715): Consider making this as a final variable. For now having a null check
// due to unit test failure. (Perhaps missing some setup)
private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig;
+ private ContentObserver mAnimationScaleObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateAnimatorDurationScale();
+ }
+ };
+
/**
* Initialize a new control panel
*
@@ -276,7 +287,8 @@ public class MediaControlPanel {
ActivityIntentHelper activityIntentHelper,
NotificationLockscreenUserManager lockscreenUserManager,
BroadcastDialogController broadcastDialogController,
- FeatureFlags featureFlags
+ FeatureFlags featureFlags,
+ GlobalSettings globalSettings
) {
mContext = context;
mBackgroundExecutor = backgroundExecutor;
@@ -305,6 +317,13 @@ public class MediaControlPanel {
});
mFeatureFlags = featureFlags;
+
+ mGlobalSettings = globalSettings;
+ mGlobalSettings.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
+ mAnimationScaleObserver
+ );
+ updateAnimatorDurationScale();
}
/**
@@ -387,6 +406,13 @@ public class MediaControlPanel {
updateSeekBarVisibility();
}
+ private void updateAnimatorDurationScale() {
+ if (mSeekBarObserver != null) {
+ mSeekBarObserver.setAnimationEnabled(
+ mGlobalSettings.getFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 1f) > 0f);
+ }
+ }
+
/**
* Get the context
*
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index 3751c60b06d5..9bc66f6c98d0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -64,9 +64,4 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlags) {
/** Check whether we allow remote media to generate resume controls */
fun isRemoteResumeAllowed() = featureFlags.isEnabled(Flags.MEDIA_REMOTE_RESUME)
-
- /** Check whether app is required to provide a non-empty media title */
- fun isMediaTitleRequired(packageName: String, user: UserHandle): Boolean {
- return StatusBarManager.isMediaTitleRequiredForApp(packageName, user)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 316c903eed5b..88ffa8da666b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -28,6 +28,7 @@ import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CheckBox;
import android.widget.TextView;
@@ -151,6 +152,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCurrentActivePosition = -1;
}
mStatusIcon.setVisibility(View.GONE);
+ enableFocusPropertyForView(mContainerLayout);
if (mController.isAnyDeviceTransferring()) {
if (device.getState() == MediaDeviceState.STATE_CONNECTING
@@ -250,7 +252,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mController.getColorItemContent());
updateGroupableCheckBox(true, isDeviceDeselectable, device);
updateEndClickArea(device, isDeviceDeselectable);
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
@@ -274,7 +277,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mController.getDeselectableMediaDevice(), device);
updateGroupableCheckBox(true, isDeviceDeselectable, device);
updateEndClickArea(device, isDeviceDeselectable);
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
@@ -282,7 +286,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
} else {
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
mCurrentActivePosition = position;
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, false /* showCheckBox */,
@@ -390,7 +395,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
View.IMPORTANT_FOR_ACCESSIBILITY_YES);
mEndTouchArea.setBackgroundTintList(
ColorStateList.valueOf(mController.getColorItemBackground()));
- setUpContentDescriptionForView(mEndTouchArea, true, device);
+ setUpContentDescriptionForView(mEndTouchArea, device);
}
private void updateGroupableCheckBox(boolean isSelected, boolean isGroupable,
@@ -471,14 +476,29 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
notifyDataSetChanged();
}
- private void setUpContentDescriptionForView(View view, boolean clickable,
- MediaDevice device) {
- view.setClickable(clickable);
+ private void disableFocusPropertyForView(View view) {
+ view.setFocusable(false);
+ view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+
+ private void enableFocusPropertyForView(View view) {
+ view.setFocusable(true);
+ view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ }
+
+ private void setUpContentDescriptionForView(View view, MediaDevice device) {
view.setContentDescription(
mContext.getString(device.getDeviceType()
== MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
? R.string.accessibility_bluetooth_name
: R.string.accessibility_cast_name, device.getName()));
+ view.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ public void onInitializeAccessibilityNodeInfo(View host,
+ AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ host.setOnClickListener(null);
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 77ff0362851a..bbd3d33e45c8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -37,6 +37,7 @@ import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE
import com.android.internal.widget.CachingIconView
import com.android.systemui.R
import com.android.app.animation.Interpolators
+import com.android.internal.logging.InstanceId
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.ui.binder.TintedIconViewBinder
import com.android.systemui.dagger.SysUISingleton
@@ -49,6 +50,7 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
import com.android.systemui.temporarydisplay.TemporaryViewInfo
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.util.animation.AnimationUtil.Companion.frames
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -82,6 +84,7 @@ open class MediaTttChipControllerReceiver @Inject constructor(
wakeLockBuilder: WakeLock.Builder,
systemClock: SystemClock,
private val rippleController: MediaTttReceiverRippleController,
+ private val temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttReceiverLogger>(
context,
logger,
@@ -94,6 +97,7 @@ open class MediaTttChipControllerReceiver @Inject constructor(
R.layout.media_ttt_chip_receiver,
wakeLockBuilder,
systemClock,
+ temporaryViewUiEventLogger,
) {
@SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
override val windowLayoutParams = commonWindowLayoutParams.apply {
@@ -125,6 +129,11 @@ open class MediaTttChipControllerReceiver @Inject constructor(
}
}
+ // A map to store instance id per route info id.
+ private var instanceMap: MutableMap<String, InstanceId> = mutableMapOf()
+
+ private val displayListener = Listener { id, _ -> instanceMap.remove(id) }
+
private fun updateMediaTapToTransferReceiverDisplay(
@StatusBarManager.MediaTransferReceiverState displayState: Int,
routeInfo: MediaRoute2Info,
@@ -139,12 +148,18 @@ open class MediaTttChipControllerReceiver @Inject constructor(
logger.logStateChangeError(displayState)
return
}
- uiEventLogger.logReceiverStateChange(chipState)
+
+ val instanceId: InstanceId = instanceMap[routeInfo.id]
+ ?: temporaryViewUiEventLogger.getNewInstanceId()
+ uiEventLogger.logReceiverStateChange(chipState, instanceId)
if (chipState != ChipStateReceiver.CLOSE_TO_SENDER) {
removeView(routeInfo.id, removalReason = chipState.name)
return
}
+
+ // Save instance id to use for logging view events.
+ instanceMap[routeInfo.id] = instanceId
if (appIcon == null) {
displayView(
ChipReceiverInfo(
@@ -152,6 +167,7 @@ open class MediaTttChipControllerReceiver @Inject constructor(
appIconDrawableOverride = null,
appName,
id = routeInfo.id,
+ instanceId = instanceId,
)
)
return
@@ -166,6 +182,7 @@ open class MediaTttChipControllerReceiver @Inject constructor(
drawable,
appName,
id = routeInfo.id,
+ instanceId = instanceId,
)
)
},
@@ -180,6 +197,7 @@ open class MediaTttChipControllerReceiver @Inject constructor(
if (mediaTttFlags.isMediaTttEnabled()) {
commandQueue.addCallback(commandQueueCallbacks)
}
+ registerListener(displayListener)
}
override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
@@ -342,4 +360,5 @@ data class ChipReceiverInfo(
override val wakeReason: String = MediaTttUtils.WAKE_REASON_RECEIVER,
override val id: String,
override val priority: ViewPriority = ViewPriority.NORMAL,
+ override val instanceId: InstanceId,
) : TemporaryViewInfo()
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
index 6e515f27c25e..2294ce180d72 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media.taptotransfer.receiver
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
@@ -25,8 +26,8 @@ import javax.inject.Inject
@SysUISingleton
class MediaTttReceiverUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
/** Logs that the receiver chip has changed states. */
- fun logReceiverStateChange(chipState: ChipStateReceiver) {
- logger.log(chipState.uiEvent)
+ fun logReceiverStateChange(chipState: ChipStateReceiver, instanceId: InstanceId) {
+ logger.log(chipState.uiEvent, instanceId)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index c7c72a9cd120..f75f8b9a18f7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -20,6 +20,7 @@ import android.app.StatusBarManager
import android.content.Context
import android.media.MediaRoute2Info
import android.view.View
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.CoreStartable
@@ -59,8 +60,8 @@ constructor(
// Since the media transfer display is similar to a heads-up notification, use the same timeout.
private val defaultTimeout = context.resources.getInteger(R.integer.heads_up_notification_decay)
- // A map to store current chip state per id.
- private var stateMap: MutableMap<String, ChipStateSender> = mutableMapOf()
+ // A map to store instance id and current chip state per id.
+ private var stateMap: MutableMap<String, Pair<InstanceId, ChipStateSender>> = mutableMapOf()
private val commandQueueCallbacks =
object : CommandQueue.Callbacks {
@@ -98,7 +99,10 @@ constructor(
return
}
- val currentStateForId: ChipStateSender? = stateMap[routeInfo.id]
+ val currentStateForId: ChipStateSender? = stateMap[routeInfo.id]?.second
+ val instanceId: InstanceId =
+ stateMap[routeInfo.id]?.first
+ ?: chipbarCoordinator.tempViewUiEventLogger.getNewInstanceId()
if (!ChipStateSender.isValidStateTransition(currentStateForId, chipState)) {
// ChipStateSender.FAR_FROM_RECEIVER is the default state when there is no state.
logger.logInvalidStateTransitionError(
@@ -107,7 +111,7 @@ constructor(
)
return
}
- uiEventLogger.logSenderStateChange(chipState)
+ uiEventLogger.logSenderStateChange(chipState, instanceId)
if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
// Return early if we're not displaying a chip for this ID anyway
@@ -131,7 +135,7 @@ constructor(
removeIdFromStore(routeInfo.id, reason = removalReason)
chipbarCoordinator.removeView(routeInfo.id, removalReason)
} else {
- stateMap[routeInfo.id] = chipState
+ stateMap[routeInfo.id] = Pair(instanceId, chipState)
logger.logStateMap(stateMap)
chipbarCoordinator.registerListener(displayListener)
chipbarCoordinator.displayView(
@@ -141,6 +145,7 @@ constructor(
undoCallback,
context,
logger,
+ instanceId,
)
)
}
@@ -155,6 +160,7 @@ constructor(
undoCallback: IUndoMediaTransferCallback?,
context: Context,
logger: MediaTttSenderLogger,
+ instanceId: InstanceId,
): ChipbarInfo {
val packageName = routeInfo.clientPackageName
val otherDeviceName =
@@ -190,6 +196,7 @@ constructor(
chipStateSender.endItem.uiEventOnClick,
chipStateSender.endItem.newState,
routeInfo,
+ instanceId,
)
} else {
null
@@ -203,6 +210,7 @@ constructor(
timeoutMs = timeout,
id = routeInfo.id,
priority = ViewPriority.NORMAL,
+ instanceId = instanceId,
)
}
@@ -217,10 +225,11 @@ constructor(
uiEvent: UiEventLogger.UiEventEnum,
@StatusBarManager.MediaTransferSenderState newState: Int,
routeInfo: MediaRoute2Info,
+ instanceId: InstanceId,
): ChipbarEndItem.Button {
val onClickListener =
View.OnClickListener {
- uiEventLogger.logUndoClicked(uiEvent)
+ uiEventLogger.logUndoClicked(uiEvent, instanceId)
undoCallback.onUndoTriggered()
// The external service should eventually send us a new TransferTriggered state, but
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
index 03bcfc8113e3..206e5e3ee090 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.taptotransfer.sender
import android.app.StatusBarManager
+import com.android.internal.logging.InstanceId
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
@@ -86,7 +87,7 @@ constructor(
}
/** Logs the current contents of the state map. */
- fun logStateMap(map: Map<String, ChipStateSender>) {
+ fun logStateMap(map: Map<String, Pair<InstanceId, ChipStateSender>>) {
buffer.log(
TAG,
LogLevel.DEBUG,
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
index af3c1b60bacf..56dbd7a23858 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.taptotransfer.sender
import android.util.Log
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
@@ -26,8 +27,8 @@ import javax.inject.Inject
@SysUISingleton
class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
/** Logs that the sender chip has changed states. */
- fun logSenderStateChange(chipState: ChipStateSender) {
- logger.log(chipState.uiEvent)
+ fun logSenderStateChange(chipState: ChipStateSender, instanceId: InstanceId) {
+ logger.log(chipState.uiEvent, instanceId)
}
/**
@@ -35,10 +36,11 @@ class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEven
*
* @param undoUiEvent the uiEvent specific to which undo button was clicked.
*/
- fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum) {
+ fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum, instanceId: InstanceId) {
val isUndoEvent =
- undoUiEvent == MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
- || undoUiEvent ==
+ undoUiEvent ==
+ MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED ||
+ undoUiEvent ==
MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
if (!isUndoEvent) {
Log.w(
@@ -47,7 +49,7 @@ class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEven
)
return
}
- logger.log(undoUiEvent)
+ logger.log(undoUiEvent, instanceId)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 1da8718b111f..8225c47d904b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -51,7 +51,6 @@ import android.view.IWallpaperVisibilityListener;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowInsets;
-import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
@@ -69,10 +68,13 @@ import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -80,8 +82,6 @@ import java.util.Optional;
import javax.inject.Inject;
-import dagger.Lazy;
-
/**
* Extracts shared elements between navbar and taskbar delegate to de-dupe logic and help them
* experience the joys of friendship.
@@ -111,6 +111,7 @@ public final class NavBarHelper implements
private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
private final List<NavbarTaskbarStateUpdater> mStateListeners = new ArrayList<>();
private final Context mContext;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
private final CommandQueue mCommandQueue;
private final ContentResolver mContentResolver;
private final EdgeBackGestureHandler mEdgeBackGestureHandler;
@@ -182,9 +183,11 @@ public final class NavBarHelper implements
IWindowManager wm,
UserTracker userTracker,
DisplayTracker displayTracker,
+ NotificationShadeWindowController notificationShadeWindowController,
DumpManager dumpManager,
CommandQueue commandQueue) {
mContext = context;
+ mNotificationShadeWindowController = notificationShadeWindowController;
mCommandQueue = commandQueue;
mContentResolver = mContext.getContentResolver();
mAccessibilityManager = accessibilityManager;
@@ -460,11 +463,7 @@ public final class NavBarHelper implements
* {@link InputMethodService} and the keyguard states.
*/
public boolean isImeShown(int vis) {
- View shadeWindowView = null;
- if (mCentralSurfacesOptionalLazy.get().isPresent()) {
- shadeWindowView =
- mCentralSurfacesOptionalLazy.get().get().getNotificationShadeWindowView();
- }
+ View shadeWindowView = mNotificationShadeWindowController.getWindowRootView();
boolean isKeyguardShowing = mKeyguardStateController.isShowing();
boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow()
&& shadeWindowView.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 1fd11bd61700..77e2847cbe76 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -607,7 +607,7 @@ class BackPanelController internal constructor(
)
}
- private var previousPreThresholdWidthInterpolator = params.entryWidthTowardsEdgeInterpolator
+ private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator
private fun preThresholdWidthStretchAmount(progress: Float): Float {
val interpolator = run {
val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop
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 cfb581b67757..cb8d87a2e620 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -20,9 +20,8 @@ import static android.view.InputDevice.SOURCE_TOUCHPAD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
-import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadFourFingerSwipe;
-import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMultiFingerSwipe;
import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll;
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -989,7 +988,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private void onMotionEvent(MotionEvent ev) {
int action = ev.getActionMasked();
- boolean isTrackpadMultiFingerSwipe = isTrackpadMultiFingerSwipe(
+ boolean isTrackpadThreeFingerSwipe = isTrackpadThreeFingerSwipe(
mIsTrackpadGestureFeaturesEnabled, ev);
if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG_MISSING_GESTURE) {
@@ -1003,7 +1002,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
// Verify if this is in within the touch region and we aren't in immersive mode, and
// either the bouncer is showing or the notification panel is hidden
mInputEventReceiver.setBatchingEnabled(false);
- if (isTrackpadMultiFingerSwipe) {
+ if (isTrackpadThreeFingerSwipe) {
// Since trackpad gestures don't have zones, this will be determined later by the
// direction of the gesture. {@code mIsOnLeftEdge} is set to false to begin with.
mDeferSetIsOnLeftEdge = true;
@@ -1019,11 +1018,11 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
&& !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
&& !isTrackpadScroll(mIsTrackpadGestureFeaturesEnabled, ev);
- if (isTrackpadMultiFingerSwipe) {
+ if (isTrackpadThreeFingerSwipe) {
// Trackpad back gestures don't have zones, so we don't need to check if the down
// event is within insets.
mAllowGesture = isBackAllowedCommon && isValidTrackpadBackGesture(
- isTrackpadMultiFingerSwipe);
+ isTrackpadThreeFingerSwipe);
} else {
mAllowGesture = isBackAllowedCommon && !mUsingThreeButtonNav && isWithinInsets
&& isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
@@ -1034,7 +1033,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mEdgeBackPlugin.onMotionEvent(ev);
dispatchToBackAnimation(ev);
}
- if (mLogGesture || isTrackpadMultiFingerSwipe) {
+ if (mLogGesture || isTrackpadThreeFingerSwipe) {
mDownPoint.set(ev.getX(), ev.getY());
mEndPoint.set(-1, -1);
mThresholdCrossed = false;
@@ -1045,10 +1044,10 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mTmpLogDate.setTime(curTime);
String curTimeStr = mLogDateFormat.format(mTmpLogDate);
(isWithinInsets ? mGestureLogInsideInsets : mGestureLogOutsideInsets).log(String.format(
- "Gesture [%d [%s],alw=%B, mltf=%B, left=%B, defLeft=%B, backAlw=%B, disbld=%B,"
+ "Gesture [%d [%s],alw=%B, t3fs=%B, left=%B, defLeft=%B, backAlw=%B, disbld=%B,"
+ " qsDisbld=%b, blkdAct=%B, pip=%B,"
+ " disp=%s, wl=%d, il=%d, wr=%d, ir=%d, excl=%s]",
- curTime, curTimeStr, mAllowGesture, isTrackpadMultiFingerSwipe,
+ curTime, curTimeStr, mAllowGesture, isTrackpadThreeFingerSwipe,
mIsOnLeftEdge, mDeferSetIsOnLeftEdge, mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisabledForQuickstep,
mGestureBlockingActivityRunning, mIsInPip, mDisplaySize,
@@ -1057,8 +1056,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
if (!mThresholdCrossed) {
mEndPoint.x = (int) ev.getX();
mEndPoint.y = (int) ev.getY();
- if (action == MotionEvent.ACTION_POINTER_DOWN && (!isTrackpadMultiFingerSwipe
- || isTrackpadFourFingerSwipe(mIsTrackpadGestureFeaturesEnabled, ev))) {
+ if (action == MotionEvent.ACTION_POINTER_DOWN && !isTrackpadThreeFingerSwipe) {
if (mAllowGesture) {
logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH);
if (DEBUG_MISSING_GESTURE) {
@@ -1070,11 +1068,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mLogGesture = false;
return;
} else if (action == MotionEvent.ACTION_MOVE) {
- if (isTrackpadFourFingerSwipe(isTrackpadMultiFingerSwipe, ev)) {
- cancelGesture(ev);
- return;
- }
- if (isTrackpadMultiFingerSwipe && mDeferSetIsOnLeftEdge) {
+ if (isTrackpadThreeFingerSwipe && mDeferSetIsOnLeftEdge) {
// mIsOnLeftEdge is determined by the relative position between the down
// and the current motion event for trackpad gestures instead of zoning.
mIsOnLeftEdge = mEndPoint.x > mDownPoint.x;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index 6d881d527ce4..9ddb78ae19ee 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -147,8 +147,21 @@ data class EdgePanelParams(private var resources: Resources) {
val flungCommittedWidthSpring = createSpring(10000f, 1f)
val flungCommittedHeightSpring = createSpring(10000f, 1f)
- val entryIndicatorAlphaThreshold = .23f
- val entryIndicatorAlphaFactor = 1.05f
+ val commonArrowDimensAlphaThreshold = .165f
+ val commonArrowDimensAlphaFactor = 1.05f
+ val commonArrowDimensAlphaSpring = Step(
+ threshold = commonArrowDimensAlphaThreshold,
+ factor = commonArrowDimensAlphaFactor,
+ postThreshold = createSpring(180f, 0.9f),
+ preThreshold = createSpring(2000f, 0.6f)
+ )
+ val commonArrowDimensAlphaSpringInterpolator = Step(
+ threshold = commonArrowDimensAlphaThreshold,
+ factor = commonArrowDimensAlphaFactor,
+ postThreshold = 1f,
+ preThreshold = 0f
+ )
+
entryIndicator = BackIndicatorDimens(
horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
@@ -162,18 +175,8 @@ data class EdgePanelParams(private var resources: Resources) {
alpha = 0f,
lengthSpring = createSpring(600f, 0.4f),
heightSpring = createSpring(600f, 0.4f),
- alphaSpring = Step(
- threshold = entryIndicatorAlphaThreshold,
- factor = entryIndicatorAlphaFactor,
- postThreshold = createSpring(200f, 1f),
- preThreshold = createSpring(2000f, 0.6f)
- ),
- alphaInterpolator = Step(
- threshold = entryIndicatorAlphaThreshold,
- factor = entryIndicatorAlphaFactor,
- postThreshold = 1f,
- preThreshold = 0f
- )
+ alphaSpring = commonArrowDimensAlphaSpring,
+ alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
@@ -188,20 +191,6 @@ data class EdgePanelParams(private var resources: Resources) {
)
)
- val preThresholdAndActiveIndicatorAlphaThreshold = .355f
- val preThresholdAndActiveIndicatorAlphaFactor = 1.05f
- val preThresholdAndActiveAlphaSpring = Step(
- threshold = preThresholdAndActiveIndicatorAlphaThreshold,
- factor = preThresholdAndActiveIndicatorAlphaFactor,
- postThreshold = createSpring(180f, 0.9f),
- preThreshold = createSpring(2000f, 0.6f)
- )
- val preThresholdAndActiveAlphaSpringInterpolator = Step(
- threshold = preThresholdAndActiveIndicatorAlphaThreshold,
- factor = preThresholdAndActiveIndicatorAlphaFactor,
- postThreshold = 1f,
- preThreshold = 0f
- )
activeIndicator = BackIndicatorDimens(
horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
@@ -214,8 +203,8 @@ data class EdgePanelParams(private var resources: Resources) {
alpha = 1f,
lengthSpring = activeCommittedArrowLengthSpring,
heightSpring = activeCommittedArrowHeightSpring,
- alphaSpring = preThresholdAndActiveAlphaSpring,
- alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
+ alphaSpring = commonArrowDimensAlphaSpring,
+ alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
@@ -242,8 +231,8 @@ data class EdgePanelParams(private var resources: Resources) {
alpha = 1f,
lengthSpring = createSpring(100f, 0.6f),
heightSpring = createSpring(100f, 0.6f),
- alphaSpring = preThresholdAndActiveAlphaSpring,
- alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
+ alphaSpring = commonArrowDimensAlphaSpring,
+ alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
index bf5e4423ff38..10a88c8b4839 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
@@ -16,6 +16,7 @@
package com.android.systemui.navigationbar.gestural;
+import static android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT;
import static android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE;
import static android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE;
@@ -29,21 +30,10 @@ public final class Utilities {
&& event.getClassification() == CLASSIFICATION_TWO_FINGER_SWIPE;
}
- public static boolean isTrackpadMultiFingerSwipe(boolean isTrackpadGestureFeaturesEnabled,
- MotionEvent event) {
- return isTrackpadGestureFeaturesEnabled
- && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
- }
-
public static boolean isTrackpadThreeFingerSwipe(boolean isTrackpadGestureFeaturesEnabled,
MotionEvent event) {
- return isTrackpadMultiFingerSwipe(isTrackpadGestureFeaturesEnabled, event)
- && event.getPointerCount() == 3;
- }
-
- public static boolean isTrackpadFourFingerSwipe(boolean isTrackpadGestureFeaturesEnabled,
- MotionEvent event) {
- return isTrackpadMultiFingerSwipe(isTrackpadGestureFeaturesEnabled, event)
- && event.getPointerCount() == 4;
+ return isTrackpadGestureFeaturesEnabled
+ && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE
+ && event.getAxisValue(AXIS_GESTURE_SWIPE_FINGER_COUNT) == 3;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
index 441b9f5d0181..a2ebeadf28b2 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
@@ -19,6 +19,7 @@ package com.android.systemui.notetask
import android.app.role.RoleManager
import android.app.role.RoleManager.ROLE_NOTES
import android.content.Context
+import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo
import android.graphics.drawable.Icon
import android.os.PersistableBundle
@@ -42,20 +43,41 @@ internal object NoteTaskRoleManagerExt {
context: Context,
user: UserHandle,
): ShortcutInfo {
+ val packageName = getDefaultRoleHolderAsUser(ROLE_NOTES, user)
+
val extras = PersistableBundle()
- getDefaultRoleHolderAsUser(ROLE_NOTES, user)?.let { packageName ->
+ if (packageName != null) {
// Set custom app badge using the icon from ROLES_NOTES default app.
extras.putString(NoteTaskController.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, packageName)
}
+ val shortLabel = context.getString(R.string.note_task_button_label)
+
+ val applicationLabel = context.packageManager.getApplicationLabel(packageName)
+ val longLabel =
+ if (applicationLabel == null) {
+ shortLabel
+ } else {
+ context.getString(
+ R.string.note_task_shortcut_long_label,
+ applicationLabel,
+ )
+ }
+
val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
return ShortcutInfo.Builder(context, NoteTaskController.SHORTCUT_ID)
.setIntent(LaunchNoteTaskActivity.newIntent(context = context))
- .setShortLabel(context.getString(R.string.note_task_button_label))
+ .setShortLabel(shortLabel)
+ .setLongLabel(longLabel)
.setLongLived(true)
.setIcon(icon)
.setExtras(extras)
.build()
}
+
+ private fun PackageManager.getApplicationLabel(packageName: String?): String? =
+ runCatching { getApplicationInfo(packageName, /* flags= */ 0)!! }
+ .getOrNull()
+ ?.let { info -> getApplicationLabel(info).toString() }
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index 444407c2341a..0ce20cdbe63d 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -73,7 +73,7 @@ constructor(
private val pickerNameResourceId = R.string.note_task_button_label
- override val pickerName: String = context.getString(pickerNameResourceId)
+ override fun pickerName(): String = context.getString(pickerNameResourceId)
override val pickerIconResourceId = R.drawable.ic_note_task_shortcut_keyguard
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 380b85cb5504..6e1ef9108256 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -20,7 +20,6 @@ import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_
import android.app.AlertDialog;
import android.content.Context;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -58,7 +57,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.Utils;
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
import com.android.systemui.Prefs;
import com.android.systemui.R;
@@ -286,7 +284,6 @@ public class InternetDialog extends SystemUIDialog implements
mHandler.removeCallbacks(mHideProgressBarRunnable);
mHandler.removeCallbacks(mHideSearchingRunnable);
mMobileNetworkLayout.setOnClickListener(null);
- mMobileDataToggle.setOnCheckedChangeListener(null);
mConnectedWifListLayout.setOnClickListener(null);
if (mSecondaryMobileNetworkLayout != null) {
mSecondaryMobileNetworkLayout.setOnClickListener(null);
@@ -351,18 +348,16 @@ public class InternetDialog extends SystemUIDialog implements
}
mInternetDialogController.connectCarrierNetwork();
});
- mMobileDataToggle.setOnCheckedChangeListener(
- (buttonView, isChecked) -> {
- if (!isChecked && shouldShowMobileDialog()) {
- showTurnOffMobileDialog();
- } else if (!shouldShowMobileDialog()) {
- if (mInternetDialogController.isMobileDataEnabled() == isChecked) {
- return;
- }
- mInternetDialogController.setMobileDataEnabled(mContext, mDefaultDataSubId,
- isChecked, false);
- }
- });
+ mMobileDataToggle.setOnClickListener(v -> {
+ boolean isChecked = mMobileDataToggle.isChecked();
+ if (!isChecked && shouldShowMobileDialog()) {
+ mMobileDataToggle.setChecked(true);
+ showTurnOffMobileDialog();
+ } else if (mInternetDialogController.isMobileDataEnabled() != isChecked) {
+ mInternetDialogController.setMobileDataEnabled(mContext, mDefaultDataSubId,
+ isChecked, false);
+ }
+ });
mConnectedWifListLayout.setOnClickListener(this::onClickConnectedWifi);
mSeeAllLayout.setOnClickListener(this::onClickSeeMoreButton);
mWiFiToggle.setOnCheckedChangeListener(
@@ -419,14 +414,6 @@ public class InternetDialog extends SystemUIDialog implements
});
});
- TypedArray array = mContext.obtainStyledAttributes(
- R.style.InternetDialog_Divider_Active, new int[]{android.R.attr.background});
- int dividerColor = Utils.getColorAttrDefaultColor(mContext,
- android.R.attr.textColorSecondary);
- mMobileToggleDivider.setBackgroundColor(isNetworkConnected
- ? array.getColor(0, dividerColor) : dividerColor);
- array.recycle();
-
mMobileDataToggle.setVisibility(mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
mMobileToggleDivider.setVisibility(
mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
@@ -696,9 +683,7 @@ public class InternetDialog extends SystemUIDialog implements
mAlertDialog = new Builder(mContext)
.setTitle(R.string.mobile_data_disable_title)
.setMessage(mContext.getString(R.string.mobile_data_disable_message, carrierName))
- .setNegativeButton(android.R.string.cancel, (d, w) -> {
- mMobileDataToggle.setChecked(true);
- })
+ .setNegativeButton(android.R.string.cancel, (d, w) -> {})
.setPositiveButton(
com.android.internal.R.string.alert_windows_notification_turn_off_action,
(d, w) -> {
@@ -708,7 +693,6 @@ public class InternetDialog extends SystemUIDialog implements
Prefs.putBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
})
.create();
- mAlertDialog.setOnCancelListener(dialog -> mMobileDataToggle.setChecked(true));
mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
SystemUIDialog.setShowForAllUsers(mAlertDialog, true);
SystemUIDialog.registerDismissListener(mAlertDialog);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 07259c2ff283..bb38b30339ef 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -200,8 +200,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
// TODO: change the method signature to use (boolean inputFocusTransferStarted)
@Override
- public void onStatusBarMotionEvent(MotionEvent event) {
- verifyCallerAndClearCallingIdentity("onStatusBarMotionEvent", () -> {
+ public void onStatusBarTouchEvent(MotionEvent event) {
+ verifyCallerAndClearCallingIdentity("onStatusBarTouchEvent", () -> {
// TODO move this logic to message queue
mCentralSurfacesOptionalLazy.get().ifPresent(centralSurfaces -> {
if (event.getActionMasked() == ACTION_DOWN) {
@@ -236,6 +236,13 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
@Override
+ public void onStatusBarTrackpadEvent(MotionEvent event) {
+ verifyCallerAndClearCallingIdentityPostMain("onStatusBarTrackpadEvent", () ->
+ mCentralSurfacesOptionalLazy.get().ifPresent(centralSurfaces ->
+ centralSurfaces.onStatusBarTrackpadEvent(event)));
+ }
+
+ @Override
public void onBackPressed() {
verifyCallerAndClearCallingIdentityPostMain("onBackPressed", () -> {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
@@ -345,7 +352,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
@Override
public void expandNotificationPanel() {
- verifyCallerAndClearCallingIdentity("expandNotificationPanel",
+ verifyCallerAndClearCallingIdentityPostMain("expandNotificationPanel",
() -> mCommandQueue.handleSystemKey(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN)));
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
new file mode 100644
index 000000000000..8f001ec6b5e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -0,0 +1,7 @@
+package com.android.systemui.scene.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+
+/** A root view of the main SysUI window that supports scenes. */
+class SceneWindowRootView(context: Context?, attrs: AttributeSet?) : WindowRootView(context, attrs) \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
new file mode 100644
index 000000000000..a0f966705381
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
@@ -0,0 +1,8 @@
+package com.android.systemui.scene.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.FrameLayout
+
+/** A view that can serve as the root of the main SysUI window. */
+open class WindowRootView(context: Context?, attrs: AttributeSet?) : FrameLayout(context, attrs) \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index bfaf3d0d2ec5..604d44967e68 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -93,6 +93,7 @@ class ScreenRecordPermissionDialog(
}
dismiss()
}
+ setCancelButtonOnClickListener { dismiss() }
initRecordOptionsView()
}
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
index 10e2afe0baa9..9a1ffcbab8d1 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
@@ -203,7 +203,10 @@ public class ScrimDrawable extends Drawable {
}
public void setBottomEdgeRadius(float radius) {
- mBottomEdgeRadius = radius;
+ if (mBottomEdgeRadius != radius) {
+ mBottomEdgeRadius = radius;
+ invalidateSelf();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 784a36092922..127c415a339a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -17,8 +17,6 @@
package com.android.systemui.shade;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
-import static android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE;
-import static android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@@ -30,6 +28,8 @@ import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
import static com.android.systemui.classifier.Classifier.GENERIC;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.UNLOCK;
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll;
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPEN;
import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPENING;
@@ -125,6 +125,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.KeyguardViewConfigurator;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
@@ -133,6 +134,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants;
import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
+import com.android.systemui.keyguard.shared.model.WakefulnessModel;
import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
@@ -598,6 +600,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private final KeyguardInteractor mKeyguardInteractor;
+ private final KeyguardViewConfigurator mKeyguardViewConfigurator;
private final @Nullable MultiShadeInteractor mMultiShadeInteractor;
private final CoroutineDispatcher mMainDispatcher;
private boolean mIsAnyMultiShadeExpanded;
@@ -740,6 +743,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
KeyguardLongPressViewModel keyguardLongPressViewModel,
KeyguardInteractor keyguardInteractor,
ActivityStarter activityStarter,
+ KeyguardViewConfigurator keyguardViewConfigurator,
KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) {
mInteractionJankMonitor = interactionJankMonitor;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@@ -762,6 +766,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mKeyguardInteractor = keyguardInteractor;
+ mKeyguardViewConfigurator = keyguardViewConfigurator;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
@@ -1319,7 +1324,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardBottomArea.initFrom(oldBottomArea);
mView.addView(mKeyguardBottomArea, index);
initBottomArea();
- mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
mStatusBarStateListener.onDozeAmountChanged(mStatusBarStateController.getDozeAmount(),
mStatusBarStateController.getInterpolatedDozeAmount());
@@ -1361,6 +1365,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardIndicationController.showTransientIndication(stringResourceId),
mVibratorHelper,
mActivityStarter);
+
+ // Rebind (for now), as a new bottom area and indication area may have been created
+ mKeyguardViewConfigurator.bindIndicationArea(mKeyguardBottomArea);
}
@VisibleForTesting
@@ -1398,7 +1405,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void setKeyguardBottomArea(KeyguardBottomAreaView keyguardBottomArea) {
mKeyguardBottomArea = keyguardBottomArea;
- mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
}
void setOpenCloseListener(OpenCloseListener openCloseListener) {
@@ -2145,10 +2151,14 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
int getFalsingThreshold() {
- float factor = mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+ float factor = ShadeViewController.getFalsingThresholdFactor(getWakefulness());
return (int) (mQsController.getFalsingThreshold() * factor);
}
+ private WakefulnessModel getWakefulness() {
+ return mKeyguardInteractor.getWakefulnessModel().getValue();
+ }
+
private void maybeAnimateBottomAreaAlpha() {
mBottomAreaShadeAlphaAnimator.cancel();
if (mBarState == StatusBarState.SHADE_LOCKED) {
@@ -2206,6 +2216,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
// TODO: non-linearly transform progress fraction into squish amount (ease-in, linear out)
mCurrentBackProgress = progressFraction;
applyBackScaling(progressFraction);
+ mQsController.setClippingBounds();
}
/** Resets back progress. */
@@ -2567,7 +2578,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
this);
return;
}
- if (mCentralSurfaces.getNotificationShadeWindowView()
+ if (mNotificationShadeWindowController.getWindowRootView()
.isVisibleToUser()) {
mView.getViewTreeObserver().removeOnGlobalLayoutListener(
this);
@@ -3022,12 +3033,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardStatusViewController.setStatusAccessibilityImportance(mode);
}
- //TODO(b/254875405): this should be removed.
- @Override
- public KeyguardBottomAreaView getKeyguardBottomAreaView() {
- return mKeyguardBottomArea;
- }
-
@Override
public void applyLaunchAnimationProgress(float linearProgress) {
boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS,
@@ -3587,8 +3592,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
expand = flingExpands(vel, vectorVel, x, y);
}
- mDozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
- mCentralSurfaces.isWakeUpComingFromTouch());
+ mDozeLog.traceFling(
+ expand,
+ mTouchAboveFalsingThreshold,
+ /* screenOnFromTouch=*/ getWakefulness().isDeviceInteractiveFromTapOrGesture());
// Log collapse gesture if on lock screen.
if (!expand && onKeyguard) {
float displayDensity = mCentralSurfaces.getDisplayDensity();
@@ -4655,6 +4662,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
boolean canCollapsePanel = canCollapsePanelOnTouch();
+ final boolean isTrackpadTwoOrThreeFingerSwipe = isTrackpadScroll(
+ mTrackpadGestureFeaturesEnabled, event) || isTrackpadThreeFingerSwipe(
+ mTrackpadGestureFeaturesEnabled, event);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
@@ -4687,7 +4697,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
addMovement(event);
break;
case MotionEvent.ACTION_POINTER_UP:
- if (isTrackpadMotionEvent(event)) {
+ if (isTrackpadTwoOrThreeFingerSwipe) {
break;
}
final int upPointer = event.getPointerId(event.getActionIndex());
@@ -4703,7 +4713,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mShadeLog.logMotionEventStatusBarState(event,
mStatusBarStateController.getState(),
"onInterceptTouchEvent: pointer down action");
- if (!isTrackpadMotionEvent(event)
+ if (!isTrackpadTwoOrThreeFingerSwipe
&& mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
mMotionAborted = true;
mVelocityTracker.clear();
@@ -4852,9 +4862,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return false;
}
+ final boolean isTrackpadTwoOrThreeFingerSwipe = isTrackpadScroll(
+ mTrackpadGestureFeaturesEnabled, event) || isTrackpadThreeFingerSwipe(
+ mTrackpadGestureFeaturesEnabled, event);
+
// On expanding, single mouse click expands the panel instead of dragging.
if (isFullyCollapsed() && (event.isFromSource(InputDevice.SOURCE_MOUSE)
- && !isTrackpadMotionEvent(event))) {
+ && !isTrackpadTwoOrThreeFingerSwipe)) {
if (event.getAction() == MotionEvent.ACTION_UP) {
expand(true /* animate */);
}
@@ -4914,7 +4928,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
break;
case MotionEvent.ACTION_POINTER_UP:
- if (isTrackpadMotionEvent(event)) {
+ if (isTrackpadTwoOrThreeFingerSwipe) {
break;
}
final int upPointer = event.getPointerId(event.getActionIndex());
@@ -4933,7 +4947,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mShadeLog.logMotionEventStatusBarState(event,
mStatusBarStateController.getState(),
"handleTouch: pointer down action");
- if (!isTrackpadMotionEvent(event)
+ if (!isTrackpadTwoOrThreeFingerSwipe
&& mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
mMotionAborted = true;
endMotionEvent(event, x, y, true /* forceCancel */);
@@ -5008,12 +5022,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mShadeLog.logHandleTouchLastReturn(event, !mGestureWaitForTouchSlop, mTracking);
return !mGestureWaitForTouchSlop || mTracking;
}
-
- private boolean isTrackpadMotionEvent(MotionEvent ev) {
- return mTrackpadGestureFeaturesEnabled && (
- ev.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE
- || ev.getClassification() == CLASSIFICATION_TWO_FINGER_SWIPE);
- }
}
private final class HeadsUpNotificationViewControllerImpl implements
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 0c800d456f3c..8105a145d15a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -103,7 +103,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private final KeyguardViewMediator mKeyguardViewMediator;
private final KeyguardBypassController mKeyguardBypassController;
private final AuthController mAuthController;
- private ViewGroup mNotificationShadeView;
+ private ViewGroup mWindowRootView;
private LayoutParams mLp;
private boolean mHasTopUi;
private boolean mHasTopUiChanged;
@@ -262,7 +262,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
- mWindowManager.addView(mNotificationShadeView, mLp);
+ mWindowManager.addView(mWindowRootView, mLp);
mLpChanged.copyFrom(mLp);
onThemeChanged();
@@ -274,13 +274,13 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
}
@Override
- public void setNotificationShadeView(ViewGroup view) {
- mNotificationShadeView = view;
+ public void setWindowRootView(ViewGroup view) {
+ mWindowRootView = view;
}
@Override
- public ViewGroup getNotificationShadeView() {
- return mNotificationShadeView;
+ public ViewGroup getWindowRootView() {
+ return mWindowRootView;
}
@Override
@@ -289,7 +289,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
}
private void setKeyguardDark(boolean dark) {
- int vis = mNotificationShadeView.getSystemUiVisibility();
+ int vis = mWindowRootView.getSystemUiVisibility();
if (dark) {
vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
@@ -297,7 +297,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
- mNotificationShadeView.setSystemUiVisibility(vis);
+ mWindowRootView.setSystemUiVisibility(vis);
}
private void applyKeyguardFlags(NotificationShadeWindowState state) {
@@ -413,11 +413,11 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
visible = true;
mLogger.d("Visibility forced to be true");
}
- if (mNotificationShadeView != null) {
+ if (mWindowRootView != null) {
if (visible) {
- mNotificationShadeView.setVisibility(View.VISIBLE);
+ mWindowRootView.setVisibility(View.VISIBLE);
} else {
- mNotificationShadeView.setVisibility(View.INVISIBLE);
+ mWindowRootView.setVisibility(View.INVISIBLE);
}
}
}
@@ -439,10 +439,10 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private void applyFitsSystemWindows(NotificationShadeWindowState state) {
boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded();
- if (mNotificationShadeView != null
- && mNotificationShadeView.getFitsSystemWindows() != fitsSystemWindows) {
- mNotificationShadeView.setFitsSystemWindows(fitsSystemWindows);
- mNotificationShadeView.requestApplyInsets();
+ if (mWindowRootView != null
+ && mWindowRootView.getFitsSystemWindows() != fitsSystemWindows) {
+ mWindowRootView.setFitsSystemWindows(fitsSystemWindows);
+ mWindowRootView.requestApplyInsets();
}
}
@@ -482,7 +482,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) {
mLogger.logApplyingWindowLayoutParams(mLp);
Trace.beginSection("updateViewLayout");
- mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
+ mWindowManager.updateViewLayout(mWindowRootView, mLp);
Trace.endSection();
}
}
@@ -608,7 +608,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
try {
final IWindowSession session = WindowManagerGlobal.getWindowSession();
session.updateTapExcludeRegion(
- IWindow.Stub.asInterface(getNotificationShadeView().getWindowToken()),
+ IWindow.Stub.asInterface(getWindowRootView().getWindowToken()),
region);
} catch (RemoteException e) {
Log.e(TAG, "could not update the tap exclusion region:" + e);
@@ -847,8 +847,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate);
pw.println(" mDeferWindowLayoutParams=" + mDeferWindowLayoutParams);
pw.println(mCurrentState);
- if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) {
- mNotificationShadeView.getViewRootImpl().dump(" ", pw);
+ if (mWindowRootView != null && mWindowRootView.getViewRootImpl() != null) {
+ mWindowRootView.getViewRootImpl().dump(" ", pw);
}
new DumpsysTableLogger(
TAG,
@@ -864,7 +864,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
@Override
public void onThemeChanged() {
- if (mNotificationShadeView == null) {
+ if (mWindowRootView == null) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index d75190e7289a..c9122c77c1d4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -59,11 +59,14 @@ import com.android.internal.view.FloatingActionMode;
import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
import com.android.systemui.R;
import com.android.systemui.compose.ComposeFacade;
+import com.android.systemui.scene.ui.view.WindowRootView;
/**
- * Combined keyguard and notification panel view. Also holding backdrop and scrims.
+ * Combined keyguard and notification panel view. Also holding backdrop and scrims. This view can
+ * serve as the root view of the main SysUI window, but because other views can also serve that
+ * purpose, users of this class cannot assume it is the root.
*/
-public class NotificationShadeWindowView extends FrameLayout {
+public class NotificationShadeWindowView extends WindowRootView {
public static final String TAG = "NotificationShadeWindowView";
private int mRightInset = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index 8672260790c3..c42c2f4fa15a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -114,6 +114,8 @@ import javax.inject.Inject;
public class QuickSettingsController implements Dumpable {
public static final String TAG = "QuickSettingsController";
+ public static final int SHADE_BACK_ANIM_SCALE_MULTIPLIER = 100;
+
private QS mQs;
private final Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
@@ -1128,7 +1130,7 @@ public class QuickSettingsController implements Dumpable {
* Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping
* as well based on the bounds of the shade and QS state.
*/
- private void setClippingBounds() {
+ void setClippingBounds() {
float qsExpansionFraction = computeExpansionFraction();
final int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction);
// Split shade has no QQS
@@ -1216,7 +1218,10 @@ public class QuickSettingsController implements Dumpable {
? 0 : mScreenCornerRadius;
radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
Math.min(top / (float) mScrimCornerRadius, 1f));
- mScrimController.setNotificationBottomRadius(radius);
+
+ float bottomRadius = mExpanded ? screenCornerRadius :
+ calculateBottomCornerRadius(screenCornerRadius);
+ mScrimController.setNotificationBottomRadius(bottomRadius);
}
if (isQsFragmentCreated()) {
float qsTranslation = 0;
@@ -1279,6 +1284,28 @@ public class QuickSettingsController implements Dumpable {
nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius);
}
+ /**
+ * Bottom corner radius should follow screen corner radius unless
+ * predictive back is running. We want a smooth transition from screen
+ * corner radius to scrim corner radius as the notification scrim is scaled down,
+ * but the transition should be brief enough to accommodate very short back gestures.
+ */
+ @VisibleForTesting
+ int calculateBottomCornerRadius(float screenCornerRadius) {
+ return (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
+ Math.min(calculateBottomRadiusProgress(), 1f));
+ }
+
+ @VisibleForTesting
+ float calculateBottomRadiusProgress() {
+ return (1 - mScrimController.getBackScaling()) * SHADE_BACK_ANIM_SCALE_MULTIPLIER;
+ }
+
+ @VisibleForTesting
+ int getScrimCornerRadius() {
+ return mScrimCornerRadius;
+ }
+
void setDisplayInsets(int leftInset, int rightInset) {
mDisplayLeftInset = leftInset;
mDisplayRightInset = rightInset;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index b7551cf3408e..1752ff6d531f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -31,7 +31,10 @@ import com.android.systemui.biometrics.AuthRippleView
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.privacy.OngoingPrivacyChip
+import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
@@ -61,17 +64,33 @@ abstract class ShadeModule {
@Provides
@SysUISingleton
+ fun providesWindowRootView(
+ layoutInflater: LayoutInflater,
+ featureFlags: FeatureFlags,
+ ): WindowRootView {
+ return if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+ layoutInflater.inflate(R.layout.scene_window_root, null)
+ } else {
+ layoutInflater.inflate(R.layout.super_notification_shade, null)
+ }
+ as WindowRootView?
+ ?: throw IllegalStateException("Window root view could not be properly inflated")
+ }
+
+ @Provides
+ @SysUISingleton
// TODO(b/277762009): Do something similar to
// {@link StatusBarWindowModule.InternalWindowView} so that only
// {@link NotificationShadeWindowViewController} can inject this view.
fun providesNotificationShadeWindowView(
- layoutInflater: LayoutInflater,
+ root: WindowRootView,
+ featureFlags: FeatureFlags,
): NotificationShadeWindowView {
- return layoutInflater.inflate(R.layout.super_notification_shade, /* root= */ null)
- as NotificationShadeWindowView?
- ?: throw IllegalStateException(
- "R.layout.super_notification_shade could not be properly inflated"
- )
+ if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
+ return root.findViewById(R.id.legacy_window_root)
+ }
+ return root as NotificationShadeWindowView?
+ ?: throw IllegalStateException("root view not a NotificationShadeWindowView")
}
// TODO(b/277762009): Only allow this view's controller to inject the view. See above.
@@ -100,6 +119,14 @@ abstract class ShadeModule {
return notificationShadeWindowView.findViewById(R.id.light_reveal_scrim)
}
+ @Provides
+ @SysUISingleton
+ fun providesKeyguardRootView(
+ notificationShadeWindowView: NotificationShadeWindowView,
+ ): KeyguardRootView {
+ return notificationShadeWindowView.findViewById(R.id.keyguard_root_view)
+ }
+
// TODO(b/277762009): Only allow this view's controller to inject the view. See above.
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index f75047c2072a..0548180807ab 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -17,11 +17,11 @@ package com.android.systemui.shade
import android.view.MotionEvent
import android.view.ViewGroup
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.statusbar.RemoteInputController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
import com.android.systemui.statusbar.phone.KeyguardStatusBarView
import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController
import java.util.function.Consumer
@@ -120,13 +120,6 @@ interface ShadeViewController {
/** Returns the StatusBarState. */
val barState: Int
- /**
- * Returns the bottom part of the keyguard, which contains quick affordances.
- *
- * TODO(b/275550429): this should be removed.
- */
- val keyguardBottomAreaView: KeyguardBottomAreaView?
-
/** Returns the NSSL controller. */
val notificationStackScrollLayoutController: NotificationStackScrollLayoutController
@@ -226,6 +219,16 @@ interface ShadeViewController {
val shadeNotificationPresenter: ShadeNotificationPresenter
companion object {
+ /**
+ * Returns a multiplicative factor to use when determining the falsing threshold for touches
+ * on the shade. The factor will be larger when the device is waking up due to a touch or
+ * gesture.
+ */
+ @JvmStatic
+ fun getFalsingThresholdFactor(wakefulness: WakefulnessModel): Float {
+ return if (wakefulness.isDeviceInteractiveFromTapOrGesture()) 1.5f else 1.0f
+ }
+
const val WAKEUP_ANIMATION_DELAY_MS = 250
const val FLING_MAX_LENGTH_SECONDS = 0.6f
const val FLING_SPEED_UP_FACTOR = 0.6f
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
index ba9d13d57a74..6d951bf4d83b 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.smartspace.dagger
+import android.app.ActivityOptions
import android.app.PendingIntent
import android.content.Intent
import android.view.View
@@ -81,7 +82,11 @@ interface SmartspaceViewComponent {
showOnLockscreen: Boolean
) {
if (showOnLockscreen) {
- pi.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pi.send(options)
} else {
activityStarter.startPendingIntentDismissingKeyguard(pi)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
index 2ca0b0054bf7..47a4641bcdd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
@@ -60,11 +60,11 @@ public interface NotificationShadeWindowController extends RemoteInputController
default void attach() {}
/** Sets the notification shade view. */
- default void setNotificationShadeView(ViewGroup view) {}
+ default void setWindowRootView(ViewGroup view) {}
/** Gets the notification shade view. */
@Nullable
- default ViewGroup getNotificationShadeView() {
+ default ViewGroup getWindowRootView() {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 7cc917f3b0b8..518825cea5e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.lockscreen
+import android.app.ActivityOptions
import android.app.PendingIntent
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
@@ -358,7 +359,11 @@ constructor(
showOnLockscreen: Boolean
) {
if (showOnLockscreen) {
- pi.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pi.send(options)
} else {
activityStarter.postStartActivityDismissingKeyguard(pi)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 0c4b0927a906..7dbca4276fcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -552,6 +552,9 @@ public class NotificationGutsManager implements NotifGutsViewManager {
Runnable r = () -> mMainHandler.post(
() -> openGutsInternal(view, x, y, menuItem));
+ // If the bouncer shows, it will block the TOUCH_UP event from reaching the notif,
+ // so explicitly mark it as unpressed here to reset the touch animation.
+ view.setPressed(false);
mActivityStarter.executeRunnableDismissingKeyguard(
r,
null /* cancelAction */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cdc7cee9de5d..c452c0fe8bad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -104,13 +104,13 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -315,7 +315,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
};
private NotificationStackScrollLogger mLogger;
- private CentralSurfaces mCentralSurfaces;
+ private NotificationsController mNotificationsController;
private ActivityStarter mActivityStarter;
private final int[] mTempInt2 = new int[2];
private boolean mGenerateChildOrderChangedEvent;
@@ -3989,7 +3989,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAmbientState.setExpansionChanging(false);
if (!mIsExpanded) {
resetScrollPosition();
- mCentralSurfaces.resetUserExpandedStates();
+ mNotificationsController.resetUserExpandedStates();
clearTemporaryViews();
clearUserLockedViews();
cancelActiveSwipe();
@@ -4570,8 +4570,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
return max + getStackTranslation();
}
- public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
- this.mCentralSurfaces = centralSurfaces;
+ public void setNotificationsController(NotificationsController notificationsController) {
+ this.mNotificationsController = notificationsController;
}
public void setActivityStarter(ActivityStarter activityStarter) {
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 7b046d6c9256..12b2ef89aab7 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
@@ -61,6 +61,7 @@ import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
@@ -69,6 +70,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEv
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.ShadeController;
+import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
@@ -98,6 +100,7 @@ import com.android.systemui.statusbar.notification.collection.render.NotifStats;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.dagger.SilentHeader;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -144,6 +147,7 @@ public class NotificationStackScrollLayoutController {
private final boolean mAllowLongPress;
private final NotificationGutsManager mNotificationGutsManager;
+ private final NotificationsController mNotificationsController;
private final NotificationVisibilityProvider mVisibilityProvider;
private final HeadsUpManagerPhone mHeadsUpManager;
private final NotificationRoundnessManager mNotificationRoundnessManager;
@@ -170,6 +174,7 @@ public class NotificationStackScrollLayoutController {
private final KeyguardMediaController mKeyguardMediaController;
private final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardBypassController mKeyguardBypassController;
+ private final KeyguardInteractor mKeyguardInteractor;
private final NotificationLockscreenUserManager mLockscreenUserManager;
// TODO: CentralSurfaces should be encapsulated behind a Controller
private final CentralSurfaces mCentralSurfaces;
@@ -428,7 +433,7 @@ public class NotificationStackScrollLayoutController {
@Override
public void onSnooze(StatusBarNotification sbn,
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
- mCentralSurfaces.setNotificationSnoozed(sbn, snoozeOption);
+ mNotificationsController.setNotificationSnoozed(sbn, snoozeOption);
}
@Override
@@ -558,7 +563,8 @@ public class NotificationStackScrollLayoutController {
@Override
public float getFalsingThresholdFactor() {
- return mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+ return ShadeViewController.getFalsingThresholdFactor(
+ mKeyguardInteractor.getWakefulnessModel().getValue());
}
@Override
@@ -612,6 +618,7 @@ public class NotificationStackScrollLayoutController {
NotificationStackScrollLayout view,
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
NotificationGutsManager notificationGutsManager,
+ NotificationsController notificationsController,
NotificationVisibilityProvider visibilityProvider,
HeadsUpManagerPhone headsUpManager,
NotificationRoundnessManager notificationRoundnessManager,
@@ -622,6 +629,7 @@ public class NotificationStackScrollLayoutController {
SysuiStatusBarStateController statusBarStateController,
KeyguardMediaController keyguardMediaController,
KeyguardBypassController keyguardBypassController,
+ KeyguardInteractor keyguardInteractor,
ZenModeController zenModeController,
NotificationLockscreenUserManager lockscreenUserManager,
Optional<NotificationListViewModel> nsslViewModel,
@@ -659,6 +667,7 @@ public class NotificationStackScrollLayoutController {
mLogger = logger;
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
+ mNotificationsController = notificationsController;
mVisibilityProvider = visibilityProvider;
mHeadsUpManager = headsUpManager;
mNotificationRoundnessManager = notificationRoundnessManager;
@@ -669,6 +678,7 @@ public class NotificationStackScrollLayoutController {
mStatusBarStateController = statusBarStateController;
mKeyguardMediaController = keyguardMediaController;
mKeyguardBypassController = keyguardBypassController;
+ mKeyguardInteractor = keyguardInteractor;
mZenModeController = zenModeController;
mLockscreenUserManager = lockscreenUserManager;
mViewModel = nsslViewModel;
@@ -708,7 +718,7 @@ public class NotificationStackScrollLayoutController {
mView.setController(this);
mView.setLogger(mLogger);
mView.setTouchHandler(new TouchHandler());
- mView.setCentralSurfaces(mCentralSurfaces);
+ mView.setNotificationsController(mNotificationsController);
mView.setActivityStarter(mActivityStarter);
mView.setClearAllAnimationListener(this::onAnimationEnd);
mView.setClearAllListener((selection) -> mUiEventLogger.log(
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 993c3801cecd..7e327e66982c 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
@@ -34,6 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.SwipeHelper;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -354,7 +355,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
@Override
protected void snapChild(final View animView, final float targetLeft, float velocity) {
- superSnapChild(animView, targetLeft, velocity);
+ if (animView instanceof SwipeableView) {
+ // only perform the snapback animation on views that are swipeable inside the shade.
+ superSnapChild(animView, targetLeft, velocity);
+ }
+
mCallback.onDragCancelled(animView);
if (targetLeft == 0) {
handleMenuCoveredOrDismissed();
@@ -541,14 +546,17 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
private final FeatureFlags mFeatureFlags;
private NotificationCallback mNotificationCallback;
private NotificationMenuRowPlugin.OnMenuEventListener mOnMenuEventListener;
+ private DumpManager mDumpManager;
private NotificationRoundnessManager mNotificationRoundnessManager;
@Inject
Builder(@Main Resources resources, ViewConfiguration viewConfiguration,
+ DumpManager dumpManager,
FalsingManager falsingManager, FeatureFlags featureFlags,
NotificationRoundnessManager notificationRoundnessManager) {
mResources = resources;
mViewConfiguration = viewConfiguration;
+ mDumpManager = dumpManager;
mFalsingManager = falsingManager;
mFeatureFlags = featureFlags;
mNotificationRoundnessManager = notificationRoundnessManager;
@@ -566,9 +574,12 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
}
NotificationSwipeHelper build() {
- return new NotificationSwipeHelper(mResources, mViewConfiguration, mFalsingManager,
+ NotificationSwipeHelper swipeHelper = new NotificationSwipeHelper(
+ mResources, mViewConfiguration, mFalsingManager,
mFeatureFlags, mNotificationCallback, mOnMenuEventListener,
mNotificationRoundnessManager);
+ mDumpManager.registerDumpable(swipeHelper);
+ return swipeHelper;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index df1a47abea98..5ad5d841fad5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -45,6 +45,7 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -68,6 +69,7 @@ constructor(
private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>,
private val shadeControllerLazy: Lazy<ShadeController>,
private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>,
+ private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>,
private val activityLaunchAnimator: ActivityLaunchAnimator,
private val context: Context,
private val lockScreenUserManager: NotificationLockscreenUserManager,
@@ -572,6 +574,9 @@ constructor(
// TODO b/221255671: restrict this to only be set for
// notifications
options.isEligibleForLegacyPermissionPrompt = true
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
return intent.sendAndReturnResult(
null,
0,
@@ -863,6 +868,7 @@ constructor(
return StatusBarLaunchAnimatorController(
animationController,
it,
+ notifShadeWindowControllerLazy.get(),
isLaunchForActivity
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 86bf7cb6fa2f..8bd9158c9189 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -26,11 +26,10 @@ import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.RemoteAnimationAdapter;
import android.view.View;
-import android.view.ViewGroup;
import android.window.RemoteTransition;
import android.window.SplashScreen;
@@ -39,19 +38,14 @@ import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.AuthKeyguardMessageArea;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.qs.QSPanelController;
-import com.android.systemui.shade.NotificationShadeWindowView;
-import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
-import com.android.systemui.statusbar.LightRevealScrim;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.util.Compile;
@@ -69,14 +63,11 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
String TAG = "CentralSurfaces";
boolean DEBUG = false;
boolean SPEW = false;
- boolean DUMPTRUCK = true; // extra dumpsys info
boolean DEBUG_GESTURES = false;
boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
boolean DEBUG_CAMERA_LIFT = false;
boolean DEBUG_WINDOW_STATE = false;
boolean DEBUG_WAKEUP_DELAY = Compile.IS_DEBUG;
- // additional instrumentation for testing purposes; intended to be left on during development
- boolean CHATTY = DEBUG;
boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
String ACTION_FAKE_ARTWORK = "fake_artwork";
int FADE_KEYGUARD_START_DELAY = 100;
@@ -217,10 +208,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
*/
void wakeUpIfDozing(long time, String why, @PowerManager.WakeReason int wakeReason);
- NotificationShadeWindowView getNotificationShadeWindowView();
-
- NotificationShadeWindowViewController getNotificationShadeWindowViewController();
-
/** */
ShadeViewController getShadeViewController();
@@ -235,12 +222,8 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
boolean isLaunchingActivityOverLockscreen();
- boolean isWakeUpComingFromTouch();
-
void onKeyguardViewManagerStatesUpdated();
- ViewGroup getNotificationScrollLayout();
-
boolean isPulsing();
boolean isOccluded();
@@ -266,8 +249,21 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
boolean isPanelExpanded();
+ /**
+ * Used to dispatch initial touch events before crossing the threshold to pull down the
+ * notification shade. After that, since the launcher window is set to slippery, input
+ * frameworks take care of routing the events to the notification shade.
+ */
void onInputFocusTransfer(boolean start, boolean cancel, float velocity);
+ /**
+ * Dispatches status bar motion event to the notification shade. This is different from
+ * {@link #onInputFocusTransfer(boolean, boolean, float)} as it doesn't rely on setting the
+ * launcher window slippery to allow the frameworks to route those events after passing the
+ * initial threshold.
+ */
+ default void onStatusBarTrackpadEvent(MotionEvent event) {}
+
void animateCollapseQuickSettings();
/** */
@@ -289,16 +285,12 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
@Override
void dump(PrintWriter pwOriginal, String[] args);
- void createAndAddWindows(@Nullable RegisterStatusBarResult result);
-
float getDisplayWidth();
float getDisplayHeight();
void readyForKeyguardDone();
- void resetUserExpandedStates();
-
void setLockscreenUser(int newUserId);
void showKeyguard();
@@ -340,8 +332,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
void showBouncerWithDimissAndCancelIfKeyguard(OnDismissAction performAction,
Runnable cancelAction);
- LightRevealScrim getLightRevealScrim();
-
// TODO: Figure out way to remove these.
NavigationBarView getNavigationBarView();
@@ -389,9 +379,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
boolean isDeviceInteractive();
- void setNotificationSnoozed(StatusBarNotification sbn,
- NotificationSwipeActionHelper.SnoozeOption snoozeOption);
-
void awakenDreams();
void clearNotificationEffects();
@@ -455,8 +442,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
void extendDozePulse();
- boolean shouldDelayWakeUpAnimation();
-
public static class KeyboardShortcutsMessage {
final int mDeviceId;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 0402d4f88205..45b65bd4b7c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -91,6 +91,7 @@ import android.view.Display;
import android.view.IRemoteAnimationRunner;
import android.view.IWindowManager;
import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
@@ -172,7 +173,6 @@ import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.qs.QSPanelController;
@@ -428,6 +428,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
public void togglePanel() {
mCommandQueueCallbacks.togglePanel();
}
+
/**
* The {@link StatusBarState} of the status bar.
*/
@@ -455,7 +456,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private PhoneStatusBarTransitions mStatusBarTransitions;
private final AuthRippleController mAuthRippleController;
@WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
- protected final NotificationShadeWindowController mNotificationShadeWindowController;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
private final StatusBarInitializer mStatusBarInitializer;
private final StatusBarWindowController mStatusBarWindowController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -464,8 +465,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private final LightRevealScrim mLightRevealScrim;
private PowerButtonReveal mPowerButtonReveal;
- private boolean mWakeUpComingFromTouch;
-
/**
* Whether we should delay the wakeup animation (which shows the notifications and moves the
* clock view). This is typically done when waking up from a 'press to unlock' gesture on a
@@ -498,7 +497,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final PluginDependencyProvider mPluginDependencyProvider;
- private final KeyguardDismissUtil mKeyguardDismissUtil;
private final ExtensionController mExtensionController;
private final UserInfoControllerImpl mUserInfoControllerImpl;
private final DemoModeController mDemoModeController;
@@ -785,7 +783,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
InitController initController,
@Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
PluginDependencyProvider pluginDependencyProvider,
- KeyguardDismissUtil keyguardDismissUtil,
ExtensionController extensionController,
UserInfoControllerImpl userInfoControllerImpl,
PhoneStatusBarPolicy phoneStatusBarPolicy,
@@ -882,7 +879,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mKeyguardViewMediatorCallback = viewMediatorCallback;
mInitController = initController;
mPluginDependencyProvider = pluginDependencyProvider;
- mKeyguardDismissUtil = keyguardDismissUtil;
mExtensionController = extensionController;
mUserInfoControllerImpl = userInfoControllerImpl;
mIconPolicy = phoneStatusBarPolicy;
@@ -1144,7 +1140,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
mMainExecutor.execute(
- () -> plugin.setup(getNotificationShadeWindowView(),
+ () -> plugin.setup(
+ mNotificationShadeWindowController.getWindowRootView(),
getNavigationBarView(),
new Callback(plugin), mDozeParameters));
}
@@ -1625,7 +1622,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
if (mDozing && mScreenOffAnimationController.allowWakeUpIfDozing()) {
mPowerManager.wakeUp(
time, wakeReason, "com.android.systemui:" + why);
- mWakeUpComingFromTouch = true;
mFalsingCollector.onScreenOnFromTouch();
}
}
@@ -1658,12 +1654,13 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
CollapsedStatusBarFragment.class,
mCentralSurfacesComponent::createCollapsedStatusBarFragment);
+ ViewGroup windowRootView = mCentralSurfacesComponent.getWindowRootView();
mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
mNotificationShadeWindowViewController = mCentralSurfacesComponent
.getNotificationShadeWindowViewController();
// TODO(b/277762009): Inject [NotificationShadeWindowView] directly into the controller.
// (Right now, there's a circular dependency.)
- mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
+ mNotificationShadeWindowController.setWindowRootView(windowRootView);
mNotificationShadeWindowViewController.setupExpandedStatusBar();
NotificationPanelViewController npvc =
mCentralSurfacesComponent.getNotificationPanelViewController();
@@ -1739,21 +1736,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
- mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
Trace.endSection();
}
@Override
- public NotificationShadeWindowView getNotificationShadeWindowView() {
- return mNotificationShadeWindowView;
- }
-
- @Override
- public NotificationShadeWindowViewController getNotificationShadeWindowViewController() {
- return mNotificationShadeWindowViewController;
- }
-
- @Override
public ShadeViewController getShadeViewController() {
return mShadeSurface;
}
@@ -1812,11 +1798,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
return mIsLaunchingActivityOverLockscreen;
}
- @Override
- public boolean isWakeUpComingFromTouch() {
- return mWakeUpComingFromTouch;
- }
-
/**
* To be called when there's a state change in StatusBarKeyguardViewManager.
*/
@@ -1826,11 +1807,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
@Override
- public ViewGroup getNotificationScrollLayout() {
- return mStackScroller;
- }
-
- @Override
public boolean isPulsing() {
return mDozeServiceHost.isPulsing();
}
@@ -1950,7 +1926,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_APPLICATION,
"com.android.systemui:full_screen_intent");
- mWakeUpComingFromTouch = false;
}
}
@@ -1991,6 +1966,11 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
@Override
+ public void onStatusBarTrackpadEvent(MotionEvent event) {
+ mCentralSurfacesComponent.getNotificationPanelViewController().handleExternalTouch(event);
+ }
+
+ @Override
public void animateCollapseQuickSettings() {
if (mState == StatusBarState.SHADE) {
mShadeSurface.collapse(
@@ -2249,8 +2229,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
+ CameraIntents.getOverrideCameraPackage(mContext));
}
- @Override
- public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
+ private void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);
mNotificationShadeWindowController.attach();
mStatusBarWindowController.attach();
@@ -2334,7 +2313,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mNotificationShadeWindowController.setNotTouchable(false);
}
finishBarAnimations();
- resetUserExpandedStates();
+ mNotificationsController.resetUserExpandedStates();
}
Trace.endSection();
}
@@ -2353,20 +2332,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
};
- @Override
- public void resetUserExpandedStates() {
- mNotificationsController.resetUserExpandedStates();
- }
-
- private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
- boolean afterKeyguardGone) {
- if (mKeyguardStateController.isShowing() && requiresShadeOpen) {
- mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
- }
- mActivityStarter.dismissKeyguardThenExecute(action, null /* cancelAction */,
- afterKeyguardGone /* afterKeyguardGone */);
- }
-
/**
* Notify the shade controller that the current user changed
*
@@ -2836,7 +2801,11 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
private void updateDozingState() {
- Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
+ Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, "Dozing", 0);
+ Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, "Dozing", String.valueOf(mDozing),
+ 0);
+ }
Trace.beginSection("CentralSurfaces#updateDozingState");
boolean keyguardVisible = mKeyguardStateController.isVisible();
@@ -3036,11 +3005,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
}
- @Override
- public LightRevealScrim getLightRevealScrim() {
- return mLightRevealScrim;
- }
-
// TODO: Figure out way to remove these.
@Override
public NavigationBarView getNavigationBarView() {
@@ -3063,9 +3027,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
protected ViewRootImpl getViewRootImpl() {
- NotificationShadeWindowView nswv = getNotificationShadeWindowView();
- if (nswv != null) return nswv.getViewRootImpl();
-
+ View root = mNotificationShadeWindowController.getWindowRootView();
+ if (root != null) return root.getViewRootImpl();
return null;
}
/**
@@ -3138,7 +3101,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
releaseGestureWakeLock();
mLaunchCameraWhenFinishedWaking = false;
mDeviceInteractive = false;
- mWakeUpComingFromTouch = false;
updateVisibleToUser();
updateNotificationPanelTouchState();
@@ -3190,6 +3152,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
@Override
public void onStartedWakingUp() {
+ // Between onStartedWakingUp() and onFinishedWakingUp(), the system is changing the
+ // display power mode. To avoid jank, animations should NOT run during these power
+ // mode transitions, which means that whenever possible, animations should
+ // start running during the onFinishedWakingUp() callback instead of this callback.
String tag = "CentralSurfaces#onStartedWakingUp";
DejankUtils.startDetectingBlockingIpcs(tag);
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
@@ -3234,6 +3200,14 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
updateVisibleToUser();
updateIsKeyguard();
+ });
+ DejankUtils.stopDetectingBlockingIpcs(tag);
+ }
+
+ @Override
+ public void onFinishedWakingUp() {
+ mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
+ // stopDozing() starts the LOCKSCREEN_TRANSITION_FROM_AOD animation.
mDozeServiceHost.stopDozing();
// This is intentionally below the stopDozing call above, since it avoids that we're
// unnecessarily animating the wakeUp transition. Animations should only be enabled
@@ -3247,13 +3221,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
if (mScreenOffAnimationController.shouldHideLightRevealScrimOnWakeUp()) {
mShadeController.makeExpandedInvisible();
}
-
});
- DejankUtils.stopDetectingBlockingIpcs(tag);
- }
-
- @Override
- public void onFinishedWakingUp() {
mWakeUpCoordinator.setFullyAwake(true);
mWakeUpCoordinator.setWakingUp(false, false);
if (mKeyguardStateController.isOccluded()
@@ -3603,12 +3571,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
};
@Override
- public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
- mNotificationsController.setNotificationSnoozed(sbn, snoozeOption);
- }
-
-
- @Override
public void awakenDreams() {
mUiBgExecutor.execute(() -> {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
index 27b68f2ffb7d..1c90c0def95f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -16,48 +16,41 @@
package com.android.systemui.statusbar.phone;
-import android.util.Log;
-
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import javax.inject.Inject;
/**
- * Executes actions that require the screen to be unlocked. Delegates the actual handling to an
- * implementation passed via {@link #setDismissHandler}.
+ * Executes actions that require the screen to be unlocked.
*/
@SysUISingleton
public class KeyguardDismissUtil implements KeyguardDismissHandler {
- private static final String TAG = "KeyguardDismissUtil";
+ private final KeyguardStateController mKeyguardStateController;
- private volatile KeyguardDismissHandler mDismissHandler;
+ private final SysuiStatusBarStateController mStatusBarStateController;
- @Inject
- public KeyguardDismissUtil() {
- }
+ private final ActivityStarter mActivityStarter;
- /** Sets the actual {@link KeyguardDismissHandler} implementation. */
- public void setDismissHandler(KeyguardDismissHandler dismissHandler) {
- mDismissHandler = dismissHandler;
+ @Inject
+ public KeyguardDismissUtil(KeyguardStateController keyguardStateController,
+ SysuiStatusBarStateController statusBarStateController,
+ ActivityStarter activityStarter) {
+ mKeyguardStateController = keyguardStateController;
+ mStatusBarStateController = statusBarStateController;
+ mActivityStarter = activityStarter;
}
- /**
- * Executes an action that requires the screen to be unlocked.
- *
- * <p>Must be called after {@link #setDismissHandler}.
- *
- * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
- */
@Override
public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
boolean afterKeyguardGone) {
- KeyguardDismissHandler dismissHandler = mDismissHandler;
- if (dismissHandler == null) {
- Log.wtf(TAG, "KeyguardDismissHandler not set.");
- action.onDismiss();
- return;
+ if (mKeyguardStateController.isShowing() && requiresShadeOpen) {
+ mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
}
- dismissHandler.executeWhenUnlocked(action, requiresShadeOpen, afterKeyguardGone);
+ mActivityStarter.dismissKeyguardThenExecute(action, null /* cancelAction */,
+ afterKeyguardGone /* afterKeyguardGone */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index a6b2bd89bfa5..f26a84ba20a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -30,6 +30,8 @@ import android.view.InsetsFlags;
import android.view.ViewDebug;
import android.view.WindowInsetsController.Appearance;
+import androidx.annotation.NonNull;
+
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.Dumpable;
@@ -46,7 +48,6 @@ import com.android.systemui.util.Compile;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Date;
import javax.inject.Inject;
@@ -57,7 +58,8 @@ import javax.inject.Inject;
public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable {
private static final String TAG = "LightBarController";
- private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean DEBUG_NAVBAR = Compile.IS_DEBUG;
+ private static final boolean DEBUG_LOGS = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
@@ -113,6 +115,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
private String mLastSetScrimStateLog;
private String mLastNavigationBarAppearanceChangedLog;
+ private StringBuilder mLogStringBuilder = null;
@Inject
public LightBarController(
@@ -193,35 +196,43 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
final boolean darkForTop = darkForQs || mGlobalActionsVisible;
mNavigationLight =
((mHasLightNavigationBar && !darkForScrim) || lightForScrim) && !darkForTop;
- mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
- + " appearance=" + appearance
- + " nbModeChanged=" + nbModeChanged
- + " navigationBarMode=" + navigationBarMode
- + " navbarColorManagedByIme=" + navbarColorManagedByIme
- + " mHasLightNavigationBar=" + mHasLightNavigationBar
- + " ignoreScrimForce=" + ignoreScrimForce
- + " darkForScrim=" + darkForScrim
- + " lightForScrim=" + lightForScrim
- + " darkForQs=" + darkForQs
- + " darkForTop=" + darkForTop
- + " mNavigationLight=" + mNavigationLight
- + " last=" + last
- + " timestamp=" + new Date();
- if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+ if (DEBUG_NAVBAR) {
+ mLastNavigationBarAppearanceChangedLog = getLogStringBuilder()
+ .append("onNavigationBarAppearanceChanged()")
+ .append(" appearance=").append(appearance)
+ .append(" nbModeChanged=").append(nbModeChanged)
+ .append(" navigationBarMode=").append(navigationBarMode)
+ .append(" navbarColorManagedByIme=").append(navbarColorManagedByIme)
+ .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+ .append(" ignoreScrimForce=").append(ignoreScrimForce)
+ .append(" darkForScrim=").append(darkForScrim)
+ .append(" lightForScrim=").append(lightForScrim)
+ .append(" darkForQs=").append(darkForQs)
+ .append(" darkForTop=").append(darkForTop)
+ .append(" mNavigationLight=").append(mNavigationLight)
+ .append(" last=").append(last)
+ .append(" timestamp=").append(System.currentTimeMillis())
+ .toString();
+ if (DEBUG_LOGS) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+ }
} else {
mNavigationLight = mHasLightNavigationBar
&& (mDirectReplying && mNavbarColorManagedByIme || !mForceDarkForScrim)
&& !mQsCustomizing;
- mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
- + " appearance=" + appearance
- + " nbModeChanged=" + nbModeChanged
- + " navigationBarMode=" + navigationBarMode
- + " navbarColorManagedByIme=" + navbarColorManagedByIme
- + " mHasLightNavigationBar=" + mHasLightNavigationBar
- + " mNavigationLight=" + mNavigationLight
- + " last=" + last
- + " timestamp=" + new Date();
- if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+ if (DEBUG_NAVBAR) {
+ mLastNavigationBarAppearanceChangedLog = getLogStringBuilder()
+ .append("onNavigationBarAppearanceChanged()")
+ .append(" appearance=").append(appearance)
+ .append(" nbModeChanged=").append(nbModeChanged)
+ .append(" navigationBarMode=").append(navigationBarMode)
+ .append(" navbarColorManagedByIme=").append(navbarColorManagedByIme)
+ .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+ .append(" mNavigationLight=").append(mNavigationLight)
+ .append(" last=").append(last)
+ .append(" timestamp=").append(System.currentTimeMillis())
+ .toString();
+ if (DEBUG_LOGS) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+ }
}
if (mNavigationLight != last) {
updateNavigation();
@@ -319,18 +330,22 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
} else {
if (mForceLightForScrim != forceLightForScrimLast) reevaluate();
}
- mLastSetScrimStateLog = "setScrimState()"
- + " scrimState=" + scrimState
- + " scrimBehindAlpha=" + scrimBehindAlpha
- + " scrimInFrontColor=" + scrimInFrontColor
- + " forceForScrim=" + forceForScrim
- + " scrimColorIsLight=" + scrimColorIsLight
- + " mHasLightNavigationBar=" + mHasLightNavigationBar
- + " mBouncerVisible=" + mBouncerVisible
- + " mForceDarkForScrim=" + mForceDarkForScrim
- + " mForceLightForScrim=" + mForceLightForScrim
- + " timestamp=" + new Date();
- if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
+ if (DEBUG_NAVBAR) {
+ mLastSetScrimStateLog = getLogStringBuilder()
+ .append("setScrimState()")
+ .append(" scrimState=").append(scrimState)
+ .append(" scrimBehindAlpha=").append(scrimBehindAlpha)
+ .append(" scrimInFrontColor=").append(scrimInFrontColor)
+ .append(" forceForScrim=").append(forceForScrim)
+ .append(" scrimColorIsLight=").append(scrimColorIsLight)
+ .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+ .append(" mBouncerVisible=").append(mBouncerVisible)
+ .append(" mForceDarkForScrim=").append(mForceDarkForScrim)
+ .append(" mForceLightForScrim=").append(mForceLightForScrim)
+ .append(" timestamp=").append(System.currentTimeMillis())
+ .toString();
+ if (DEBUG_LOGS) Log.d(TAG, mLastSetScrimStateLog);
+ }
} else {
boolean forceDarkForScrimLast = mForceDarkForScrim;
// For BOUNCER/BOUNCER_SCRIMMED cases, we assume that alpha is always below threshold.
@@ -344,15 +359,28 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
if (mHasLightNavigationBar && (mForceDarkForScrim != forceDarkForScrimLast)) {
reevaluate();
}
- mLastSetScrimStateLog = "setScrimState()"
- + " scrimState=" + scrimState
- + " scrimBehindAlpha=" + scrimBehindAlpha
- + " scrimInFrontColor=" + scrimInFrontColor
- + " mHasLightNavigationBar=" + mHasLightNavigationBar
- + " mForceDarkForScrim=" + mForceDarkForScrim
- + " timestamp=" + new Date();
- if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
+ if (DEBUG_NAVBAR) {
+ mLastSetScrimStateLog = getLogStringBuilder()
+ .append("setScrimState()")
+ .append(" scrimState=").append(scrimState)
+ .append(" scrimBehindAlpha=").append(scrimBehindAlpha)
+ .append(" scrimInFrontColor=").append(scrimInFrontColor)
+ .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+ .append(" mForceDarkForScrim=").append(mForceDarkForScrim)
+ .append(" timestamp=").append(System.currentTimeMillis())
+ .toString();
+ if (DEBUG_LOGS) Log.d(TAG, mLastSetScrimStateLog);
+ }
+ }
+ }
+
+ @NonNull
+ private StringBuilder getLogStringBuilder() {
+ if (mLogStringBuilder == null) {
+ mLogStringBuilder = new StringBuilder();
}
+ mLogStringBuilder.setLength(0);
+ return mLogStringBuilder;
}
private static boolean isLight(int appearance, int barMode, int flag) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index fdb772bc6c13..25ecf1a424e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -602,6 +602,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mNotificationsScrim.setScaleY(scale);
}
+ public float getBackScaling() {
+ return mNotificationsScrim.getScaleY();
+ }
+
public void onTrackingStarted() {
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 0414a14205d7..f11b8e2713ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -495,6 +495,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return mKeyguardStateController.isShowing()
&& !primaryBouncerIsOrWillBeShowing()
+ && !mKeyguardStateController.isKeyguardGoingAway()
&& isUserTrackingStarted
&& !hideBouncerOverDream
&& !mKeyguardStateController.isOccluded()
@@ -749,7 +750,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void onStartedWakingUp() {
- mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
+ mNotificationShadeWindowController.getWindowRootView().getWindowInsetsController()
.setAnimationsDisabled(false);
NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
if (navBarView != null) {
@@ -763,7 +764,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void onStartedGoingToSleep() {
- mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
+ mNotificationShadeWindowController.getWindowRootView().getWindowInsetsController()
.setAnimationsDisabled(true);
NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
if (navBarView != null) {
@@ -1113,7 +1114,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (view != null) {
view.setVisibility(View.VISIBLE);
}
- mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
+ mNotificationShadeWindowController.getWindowRootView().getWindowInsetsController()
.show(navigationBars());
}
};
@@ -1191,7 +1192,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
} else {
mNotificationContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
- mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
+ mNotificationShadeWindowController.getWindowRootView().getWindowInsetsController()
.hide(navigationBars());
}
}
@@ -1311,7 +1312,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public ViewRootImpl getViewRootImpl() {
- ViewGroup viewGroup = mNotificationShadeWindowController.getNotificationShadeView();
+ ViewGroup viewGroup = mNotificationShadeWindowController.getWindowRootView();
if (viewGroup != null) {
return viewGroup.getViewRootImpl();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
index 9f69db93e64a..00ac3f4cdc11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
@@ -3,6 +3,7 @@ package com.android.systemui.statusbar.phone
import android.view.View
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.animation.LaunchAnimator
+import com.android.systemui.statusbar.NotificationShadeWindowController
/**
* A [ActivityLaunchAnimator.Controller] that takes care of collapsing the status bar at the right
@@ -11,12 +12,13 @@ import com.android.systemui.animation.LaunchAnimator
class StatusBarLaunchAnimatorController(
private val delegate: ActivityLaunchAnimator.Controller,
private val centralSurfaces: CentralSurfaces,
+ private val notificationShadeWindowController: NotificationShadeWindowController,
private val isLaunchForActivity: Boolean = true
) : ActivityLaunchAnimator.Controller by delegate {
// Always sync the opening window with the shade, given that we draw a hole punch in the shade
// of the same size and position as the opening app to make it visible.
override val openingWindowSyncView: View?
- get() = centralSurfaces.notificationShadeWindowView
+ get() = notificationShadeWindowController.windowRootView
override fun onIntentStarted(willAnimate: Boolean) {
delegate.onIntentStarted(willAnimate)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 7bbb03b4bc94..28ec1ac5e593 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -63,6 +63,7 @@ import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -122,6 +123,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
private final CentralSurfaces mCentralSurfaces;
private final NotificationPresenter mPresenter;
private final ShadeViewController mNotificationPanel;
+ private final NotificationShadeWindowController mNotificationShadeWindowController;
private final ActivityLaunchAnimator mActivityLaunchAnimator;
private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
private final UserTracker mUserTracker;
@@ -157,6 +159,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
CentralSurfaces centralSurfaces,
NotificationPresenter presenter,
ShadeViewController panel,
+ NotificationShadeWindowController notificationShadeWindowController,
ActivityLaunchAnimator activityLaunchAnimator,
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
LaunchFullScreenIntentProvider launchFullScreenIntentProvider,
@@ -182,6 +185,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mLockPatternUtils = lockPatternUtils;
mStatusBarRemoteInputCallback = remoteInputCallback;
mActivityIntentHelper = activityIntentHelper;
+ mNotificationShadeWindowController = notificationShadeWindowController;
mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
@@ -437,6 +441,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
new StatusBarLaunchAnimatorController(
mNotificationAnimationProvider.getAnimatorController(row, null),
mCentralSurfaces,
+ mNotificationShadeWindowController,
isActivityIntent);
mActivityLaunchAnimator.startPendingIntentWithAnimation(
animationController,
@@ -475,7 +480,9 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
ActivityLaunchAnimator.Controller animationController =
new StatusBarLaunchAnimatorController(
mNotificationAnimationProvider.getAnimatorController(row),
- mCentralSurfaces, true /* isActivityIntent */);
+ mCentralSurfaces,
+ mNotificationShadeWindowController,
+ true /* isActivityIntent */);
mActivityLaunchAnimator.startIntentWithAnimation(
animationController, animate, intent.getPackage(),
@@ -520,9 +527,11 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
);
ActivityLaunchAnimator.Controller animationController =
viewController == null ? null
- : new StatusBarLaunchAnimatorController(viewController,
+ : new StatusBarLaunchAnimatorController(
+ viewController,
mCentralSurfaces,
- true /* isActivityIntent */);
+ mNotificationShadeWindowController,
+ true /* isActivityIntent */);
mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
intent.getPackage(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index dfaee4c674ad..5624e28204cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -40,7 +40,6 @@ import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -86,7 +85,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private final HeadsUpManagerPhone mHeadsUpManager;
private final AboveShelfObserver mAboveShelfObserver;
private final DozeScrimController mDozeScrimController;
- private final KeyguardIndicationController mKeyguardIndicationController;
private final CentralSurfaces mCentralSurfaces;
private final LockscreenShadeTransitionController mShadeTransitionController;
private final CommandQueue mCommandQueue;
@@ -115,7 +113,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationShadeWindowController notificationShadeWindowController,
DynamicPrivacyController dynamicPrivacyController,
KeyguardStateController keyguardStateController,
- KeyguardIndicationController keyguardIndicationController,
CentralSurfaces centralSurfaces,
LockscreenShadeTransitionController shadeTransitionController,
CommandQueue commandQueue,
@@ -137,7 +134,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mQsController = quickSettingsController;
mHeadsUpManager = headsUp;
mDynamicPrivacyController = dynamicPrivacyController;
- mKeyguardIndicationController = keyguardIndicationController;
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mCentralSurfaces = centralSurfaces;
mShadeTransitionController = shadeTransitionController;
@@ -173,7 +169,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mNotificationPanel.getShadeNotificationPresenter().createRemoteInputDelegate());
initController.addPostInitTask(() -> {
- mKeyguardIndicationController.init();
mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 592d1aa8f43f..96a4d900c160 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -22,6 +22,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.statusbar.CircleReveal
import com.android.systemui.statusbar.LightRevealScrim
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.notification.AnimatableProperty
@@ -60,6 +61,7 @@ class UnlockedScreenOffAnimationController @Inject constructor(
private val keyguardStateController: KeyguardStateController,
private val dozeParameters: dagger.Lazy<DozeParameters>,
private val globalSettings: GlobalSettings,
+ private val notifShadeWindowControllerLazy: dagger.Lazy<NotificationShadeWindowController>,
private val interactionJankMonitor: InteractionJankMonitor,
private val powerManager: PowerManager,
private val handler: Handler = Handler()
@@ -114,7 +116,7 @@ class UnlockedScreenOffAnimationController @Inject constructor(
override fun onAnimationStart(animation: Animator?) {
interactionJankMonitor.begin(
- mCentralSurfaces.notificationShadeWindowView, CUJ_SCREEN_OFF)
+ notifShadeWindowControllerLazy.get().windowRootView, CUJ_SCREEN_OFF)
}
})
}
@@ -218,7 +220,7 @@ class UnlockedScreenOffAnimationController @Inject constructor(
.setCustomInterpolator(View.ALPHA, Interpolators.FAST_OUT_SLOW_IN),
true /* animate */)
interactionJankMonitor.begin(
- mCentralSurfaces.notificationShadeWindowView,
+ notifShadeWindowControllerLazy.get().windowRootView,
CUJ_SCREEN_OFF_SHOW_AOD
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 273e78350f27..158f96123d92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.ST
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import com.android.systemui.scene.ui.view.WindowRootView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
@@ -80,8 +81,11 @@ public interface CentralSurfacesComponent {
@Scope
@interface CentralSurfacesScope {}
+ /** Creates the root view of the main SysUI window}. */
+ WindowRootView getWindowRootView();
+
/**
- * Creates a {@link NotificationShadeWindowView}.
+ * Creates or returns a {@link NotificationShadeWindowView}.
*/
NotificationShadeWindowView getNotificationShadeWindowView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index b36ba3845fe9..d42e30c9b1b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -110,6 +110,9 @@ interface MobileIconInteractor {
/** See [MobileIconsInteractor.isForceHidden]. */
val isForceHidden: Flow<Boolean>
+
+ /** True when in carrier network change mode */
+ val carrierNetworkChangeActive: StateFlow<Boolean>
}
/** Interactor for a single mobile connection. This connection _should_ have one subscription ID */
@@ -135,6 +138,9 @@ class MobileIconInteractorImpl(
override val isDataEnabled: StateFlow<Boolean> = connectionRepository.dataEnabled
+ override val carrierNetworkChangeActive: StateFlow<Boolean> =
+ connectionRepository.carrierNetworkChangeActive
+
// True if there exists _any_ icon override for this carrierId. Note that overrides can include
// any or none of the icon groups defined in MobileMappings, so we still need to check on a
// per-network-type basis whether or not the given icon group is overridden
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index 5b7d45b55c5c..a2a247a279fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -109,12 +109,7 @@ object MobileIconBinder {
viewModel.subscriptionId,
icon,
)
- mobileDrawable.level =
- SignalDrawable.getState(
- icon.level,
- icon.numberOfLevels,
- icon.showExclamationMark,
- )
+ mobileDrawable.level = icon.toSignalDrawableState()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt
index be2e41a2a581..6de3f85027ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.model
+import com.android.settingslib.graph.SignalDrawable
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
@@ -24,6 +25,7 @@ data class SignalIconModel(
val level: Int,
val numberOfLevels: Int,
val showExclamationMark: Boolean,
+ val carrierNetworkChange: Boolean,
) : Diffable<SignalIconModel> {
// TODO(b/267767715): Can we implement [logDiffs] and [logFull] generically for data classes?
override fun logDiffs(prevVal: SignalIconModel, row: TableRowLogger) {
@@ -36,17 +38,30 @@ data class SignalIconModel(
if (prevVal.showExclamationMark != showExclamationMark) {
row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark)
}
+ if (prevVal.carrierNetworkChange != carrierNetworkChange) {
+ row.logChange(COL_CARRIER_NETWORK_CHANGE, carrierNetworkChange)
+ }
}
override fun logFull(row: TableRowLogger) {
row.logChange(COL_LEVEL, level)
row.logChange(COL_NUM_LEVELS, numberOfLevels)
row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark)
+ row.logChange(COL_CARRIER_NETWORK_CHANGE, carrierNetworkChange)
}
+ /** Convert this model to an [Int] consumable by [SignalDrawable]. */
+ fun toSignalDrawableState(): Int =
+ if (carrierNetworkChange) {
+ SignalDrawable.getCarrierChangeState(numberOfLevels)
+ } else {
+ SignalDrawable.getState(level, numberOfLevels, showExclamationMark)
+ }
+
companion object {
private const val COL_LEVEL = "level"
private const val COL_NUM_LEVELS = "numLevels"
private const val COL_SHOW_EXCLAMATION = "showExclamation"
+ private const val COL_CARRIER_NETWORK_CHANGE = "carrierNetworkChange"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 54730ed82564..35f4f9aa4622 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -122,13 +122,20 @@ constructor(
level = shownLevel.value,
numberOfLevels = iconInteractor.numberOfLevels.value,
showExclamationMark = showExclamationMark.value,
+ carrierNetworkChange = iconInteractor.carrierNetworkChangeActive.value,
)
combine(
shownLevel,
iconInteractor.numberOfLevels,
showExclamationMark,
- ) { shownLevel, numberOfLevels, showExclamationMark ->
- SignalIconModel(shownLevel, numberOfLevels, showExclamationMark)
+ iconInteractor.carrierNetworkChangeActive,
+ ) { shownLevel, numberOfLevels, showExclamationMark, carrierNetworkChange ->
+ SignalIconModel(
+ shownLevel,
+ numberOfLevels,
+ showExclamationMark,
+ carrierNetworkChange,
+ )
}
.distinctUntilChanged()
.logDiffsForTable(
@@ -152,8 +159,10 @@ constructor(
iconInteractor.isDataEnabled,
iconInteractor.alwaysShowDataRatIcon,
iconInteractor.mobileIsDefault,
- ) { dataConnected, dataEnabled, alwaysShow, mobileIsDefault ->
- alwaysShow || (dataEnabled && dataConnected && mobileIsDefault)
+ iconInteractor.carrierNetworkChangeActive,
+ ) { dataConnected, dataEnabled, alwaysShow, mobileIsDefault, carrierNetworkChange ->
+ alwaysShow ||
+ (!carrierNetworkChange && (dataEnabled && dataConnected && mobileIsDefault))
}
.distinctUntilChanged()
.logDiffsForTable(
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index 59122aff7f21..8f0489631ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -79,6 +79,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
@LayoutRes private val viewLayoutRes: Int,
private val wakeLockBuilder: WakeLock.Builder,
private val systemClock: SystemClock,
+ internal val tempViewUiEventLogger: TemporaryViewUiEventLogger,
) : CoreStartable, Dumpable {
/**
* Window layout params that will be used as a starting point for the [windowLayoutParams] of
@@ -207,6 +208,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
private fun showNewView(newDisplayInfo: DisplayInfo, timeout: Int) {
logger.logViewAddition(newDisplayInfo.info)
+ tempViewUiEventLogger.logViewAdded(newDisplayInfo.info.instanceId)
createAndAcquireWakeLock(newDisplayInfo)
updateTimeout(newDisplayInfo, timeout)
inflateAndUpdateView(newDisplayInfo)
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
index 5596cf68b4bc..48bd047a6f9b 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
@@ -16,6 +16,8 @@
package com.android.systemui.temporarydisplay
+import com.android.internal.logging.InstanceId
+
/**
* A superclass view state used with [TemporaryViewDisplayController].
*/
@@ -45,6 +47,9 @@ abstract class TemporaryViewInfo {
/** The priority for this view. */
abstract val priority: ViewPriority
+
+ /** Instance ID for logging purposes */
+ abstract val instanceId: InstanceId?
}
const val DEFAULT_TIMEOUT_MILLIS = 10000
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt
new file mode 100644
index 000000000000..1345851bea43
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.InstanceIdSequence
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+private const val INSTANCE_ID_MAX = 1 shl 20
+
+/** A helper class to log events related to the temporary view */
+@SysUISingleton
+class TemporaryViewUiEventLogger @Inject constructor(val logger: UiEventLogger) {
+
+ private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX)
+
+ /** Get a new instance ID for a new media control */
+ fun getNewInstanceId(): InstanceId {
+ return instanceIdSequence.newInstanceId()
+ }
+
+ /** Logs that view is added */
+ fun logViewAdded(instanceId: InstanceId?) {
+ logger.log(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED, instanceId)
+ }
+
+ /** Logs that view is manually dismissed by user */
+ fun logViewManuallyDismissed(instanceId: InstanceId?) {
+ logger.log(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED, instanceId)
+ }
+}
+
+enum class TemporaryViewUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The temporary view was added to window manager") TEMPORARY_VIEW_ADDED(1389),
+ @UiEvent(doc = "The temporary view was manually dismissed")
+ TEMPORARY_VIEW_MANUALLY_DISMISSED(1390);
+
+ override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index ab6409b5f9b3..7ed56e72f759 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -52,6 +52,7 @@ import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
@@ -92,6 +93,7 @@ constructor(
private val vibratorHelper: VibratorHelper,
wakeLockBuilder: WakeLock.Builder,
systemClock: SystemClock,
+ tempViewUiEventLogger: TemporaryViewUiEventLogger,
) :
TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
context,
@@ -105,6 +107,7 @@ constructor(
R.layout.chipbar,
wakeLockBuilder,
systemClock,
+ tempViewUiEventLogger,
) {
private lateinit var parent: ChipbarRootView
@@ -315,6 +318,7 @@ constructor(
)
return
}
+ tempViewUiEventLogger.logViewManuallyDismissed(currentDisplayInfo.info.instanceId)
removeView(currentDisplayInfo.info.id, SWIPE_UP_GESTURE_REASON)
updateGestureListening()
}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index 52f2d11f814e..1d50241f4586 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -19,6 +19,7 @@ package com.android.systemui.temporarydisplay.chipbar
import android.os.VibrationEffect
import android.view.View
import androidx.annotation.AttrRes
+import com.android.internal.logging.InstanceId
import com.android.systemui.R
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
@@ -47,6 +48,7 @@ data class ChipbarInfo(
override val timeoutMs: Int,
override val id: String,
override val priority: ViewPriority,
+ override val instanceId: InstanceId?,
) : TemporaryViewInfo() {
companion object {
// LINT.IfChange
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
index 57b9f914d4d6..ae4820837ce5 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -18,10 +18,11 @@ package com.android.systemui.theme
import android.util.Pair
import com.android.systemui.monet.dynamiccolor.DynamicColor
-import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors as MDC
+import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors
class DynamicColors {
companion object {
+ private val MDC = MaterialDynamicColors()
@JvmField
val ALL_DYNAMIC_COLORS_MAPPED: List<Pair<String, DynamicColor>> =
arrayListOf(
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index c1999b284553..b78329cfa5aa 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -659,6 +659,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
Resources res = userHandle.isSystem()
? mResources : mContext.createContextAsUser(userHandle, 0).getResources();
Resources.Theme theme = mContext.getTheme();
+ MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
if (!(res.getColor(android.R.color.system_accent1_500, theme)
== mColorScheme.getAccent1().getS500()
&& res.getColor(android.R.color.system_accent2_500, theme)
@@ -670,15 +671,15 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
&& res.getColor(android.R.color.system_neutral2_500, theme)
== mColorScheme.getNeutral2().getS500()
&& res.getColor(android.R.color.system_outline_variant_dark, theme)
- == MaterialDynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
+ == dynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
&& res.getColor(android.R.color.system_outline_variant_light, theme)
- == MaterialDynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
+ == dynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
&& res.getColor(android.R.color.system_primary_container_dark, theme)
- == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
+ == dynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
&& res.getColor(android.R.color.system_primary_container_light, theme)
- == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
+ == dynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
&& res.getColor(android.R.color.system_primary_fixed, theme)
- == MaterialDynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
+ == dynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 2709da38a7d8..992b0221068c 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -18,16 +18,19 @@ package com.android.systemui.unfold
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
+import android.os.SystemProperties
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.system.SystemUnfoldSharedModule
+import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.updates.FoldStateProvider
import com.android.systemui.unfold.updates.RotationChangeProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
+import com.android.systemui.unfold.util.UnfoldOnlyProgressProvider
import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
import com.android.systemui.util.time.SystemClockImpl
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
@@ -37,6 +40,7 @@ import dagger.Provides
import java.util.Optional
import java.util.concurrent.Executor
import javax.inject.Named
+import javax.inject.Provider
import javax.inject.Singleton
@Module(includes = [UnfoldSharedModule::class, SystemUnfoldSharedModule::class])
@@ -91,6 +95,18 @@ class UnfoldTransitionModule {
}
@Provides
+ @Singleton
+ @Named(UNFOLD_ONLY_PROVIDER)
+ fun provideUnfoldOnlyProvider(
+ foldProvider: FoldProvider,
+ @Main executor: Executor,
+ sourceProvider: Optional<UnfoldTransitionProgressProvider>
+ ): Optional<UnfoldTransitionProgressProvider> =
+ sourceProvider.map { provider ->
+ UnfoldOnlyProgressProvider(foldProvider, executor, provider)
+ }
+
+ @Provides
@Named(UNFOLD_STATUS_BAR)
@Singleton
fun provideStatusBarScopedTransitionProvider(
@@ -102,16 +118,35 @@ class UnfoldTransitionModule {
@Singleton
fun provideShellProgressProvider(
config: UnfoldTransitionConfig,
- provider: Optional<UnfoldTransitionProgressProvider>
- ): ShellUnfoldProgressProvider =
- if (config.isEnabled && provider.isPresent) {
- UnfoldProgressProvider(provider.get())
- } else {
- ShellUnfoldProgressProvider.NO_PROVIDER
- }
+ provider: Provider<Optional<UnfoldTransitionProgressProvider>>,
+ @Named(UNFOLD_ONLY_PROVIDER)
+ unfoldOnlyProvider: Provider<Optional<UnfoldTransitionProgressProvider>>
+ ): ShellUnfoldProgressProvider {
+ val resultingProvider =
+ if (config.isEnabled) {
+ // Return unfold only provider to the shell if we don't want to animate tasks during
+ // folding. Shell provider listeners are responsible for animating task bounds.
+ if (ENABLE_FOLD_TASK_ANIMATIONS) {
+ provider
+ } else {
+ unfoldOnlyProvider
+ }
+ } else {
+ null
+ }
+
+ return resultingProvider?.get()?.orElse(null)?.let(::UnfoldProgressProvider)
+ ?: ShellUnfoldProgressProvider.NO_PROVIDER
+ }
@Provides
fun screenStatusProvider(impl: LifecycleScreenStatusProvider): ScreenStatusProvider = impl
}
const val UNFOLD_STATUS_BAR = "unfold_status_bar"
+const val UNFOLD_ONLY_PROVIDER = "unfold_only_provider"
+
+// TODO: b/265764985 - tracking bug to clean-up the flag
+// FeatureFlags are not accessible here because it's a global submodule (see GlobalModule.java)
+private val ENABLE_FOLD_TASK_ANIMATIONS =
+ SystemProperties.getBoolean("persist.unfold.enable_fold_tasks_animation", false)
diff --git a/packages/SystemUI/src/com/android/systemui/util/ActivityTaskManagerProxy.kt b/packages/SystemUI/src/com/android/systemui/util/ActivityTaskManagerProxy.kt
new file mode 100644
index 000000000000..6e82cf673307
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ActivityTaskManagerProxy.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.app.ActivityTaskManager
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** Proxy for static calls to [ActivityTaskManager]. */
+@SysUISingleton
+class ActivityTaskManagerProxy @Inject constructor() {
+
+ /** Calls [ActivityTaskManager.supportsMultiWindow] */
+ fun supportsMultiWindow(context: Context) = ActivityTaskManager.supportsMultiWindow(context)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 5bd965c2f668..b24a69292186 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -404,6 +404,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
@Override
public void destroy() {
+ Log.d(TAG, "destroy() called");
mController.removeCallback(mControllerCallbackH);
mHandler.removeCallbacksAndMessages(null);
mConfigurationController.removeCallback(this);
@@ -465,6 +466,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
private void initDialog(int lockTaskModeState) {
+ Log.d(TAG, "initDialog: called!");
mDialog = new CustomDialog(mContext);
initDimens();
@@ -1269,7 +1271,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
protected void tryToRemoveCaptionsTooltip() {
- if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
+ if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null && mDialog != null) {
ViewGroup container = mDialog.findViewById(R.id.volume_dialog_container);
container.removeView(mODICaptionsTooltipView);
mODICaptionsTooltipView = null;
@@ -1476,8 +1478,16 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
- if (mIsAnimatingDismiss) {
- Log.d(TAG, "dismissH: isAnimatingDismiss");
+
+ boolean showingStateInconsistent = !mShowing && mDialog != null && mDialog.isShowing();
+ // If incorrectly assuming dialog is not showing, continue and make the state consistent.
+ if (showingStateInconsistent) {
+ Log.d(TAG, "dismissH: volume dialog possible in inconsistent state:"
+ + "mShowing=" + mShowing + ", mDialog==null?" + (mDialog == null));
+ }
+ if (mIsAnimatingDismiss && !showingStateInconsistent) {
+ Log.d(TAG, "dismissH: skipping dismiss because isAnimatingDismiss is true"
+ + " and showingStateInconsistent is false");
Trace.endSection();
return;
}
@@ -1495,8 +1505,12 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
.setDuration(mDialogHideAnimationDurationMs)
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
.withEndAction(() -> mHandler.postDelayed(() -> {
- mController.notifyVisible(false);
- mDialog.dismiss();
+ if (mController != null) {
+ mController.notifyVisible(false);
+ }
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
tryToRemoveCaptionsTooltip();
mIsAnimatingDismiss = false;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index dfc6392404a4..cab47a3c4b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -307,6 +307,8 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
walletCard.getPendingIntent().send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.w(TAG, "Error sending pending intent for wallet card.");
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 3f1560bc5fce..8c71392caeec 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -53,6 +53,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
@@ -62,6 +63,7 @@ import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import java.util.TimeZone
import java.util.concurrent.Executor
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class)
@@ -117,6 +119,7 @@ class ClockEventControllerTest : SysuiTestCase() {
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = bouncerRepository,
+ configurationRepository = FakeConfigurationRepository(),
),
KeyguardTransitionInteractor(repository = transitionRepository),
broadcastDispatcher,
@@ -155,9 +158,8 @@ class ClockEventControllerTest : SysuiTestCase() {
@Test
fun themeChanged_verifyClockPaletteUpdated() = runBlocking(IMMEDIATE) {
- // TODO(b/266103601): delete this test and add more coverage for updateColors()
- // verify(smallClockEvents).onRegionDarknessChanged(anyBoolean())
- // verify(largeClockEvents).onRegionDarknessChanged(anyBoolean())
+ verify(smallClockEvents).onRegionDarknessChanged(anyBoolean())
+ verify(largeClockEvents).onRegionDarknessChanged(anyBoolean())
val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
verify(configurationController).addCallback(capture(captor))
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index fb738454fc71..b21cc6dde815 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -150,6 +150,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
.thenReturn(100);
when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
.thenReturn(-200);
+ when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
+ .thenReturn(View.INVISIBLE);
when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 565fc57e81b7..f6450a4fb563 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -253,11 +253,11 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
getViewConstraint(mSecurityViewFlipper.getId());
ConstraintSet.Constraint userSwitcherConstraint =
getViewConstraint(R.id.keyguard_bouncer_user_switcher);
- assertThat(viewFlipperConstraint.layout.rightToRight).isEqualTo(PARENT_ID);
- assertThat(viewFlipperConstraint.layout.leftToRight).isEqualTo(
+ assertThat(viewFlipperConstraint.layout.endToEnd).isEqualTo(PARENT_ID);
+ assertThat(viewFlipperConstraint.layout.startToEnd).isEqualTo(
R.id.keyguard_bouncer_user_switcher);
- assertThat(userSwitcherConstraint.layout.leftToLeft).isEqualTo(PARENT_ID);
- assertThat(userSwitcherConstraint.layout.rightToLeft).isEqualTo(
+ assertThat(userSwitcherConstraint.layout.startToStart).isEqualTo(PARENT_ID);
+ assertThat(userSwitcherConstraint.layout.endToStart).isEqualTo(
mSecurityViewFlipper.getId());
assertThat(viewFlipperConstraint.layout.topToTop).isEqualTo(PARENT_ID);
assertThat(viewFlipperConstraint.layout.bottomToBottom).isEqualTo(PARENT_ID);
@@ -377,7 +377,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
ConstraintSet.Constraint viewFlipperConstraint = getViewConstraint(
mSecurityViewFlipper.getId());
- assertThat(viewFlipperConstraint.layout.leftToLeft).isEqualTo(PARENT_ID);
+ assertThat(viewFlipperConstraint.layout.startToStart).isEqualTo(PARENT_ID);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
index 68dc6c04bc79..4d3243a2ccf6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
@@ -15,11 +15,13 @@
*/
package com.android.keyguard;
+import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.pm.PackageManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -76,12 +78,20 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase {
@Test
public void refresh_replacesSliceContentAndNotifiesListener() {
+ // Skips the test if running on a watch because watches don't have a SliceManager system
+ // service.
+ assumeFalse(isWatch());
+
mController.refresh();
verify(mView).hideSlice();
}
@Test
public void onAttachedToWindow_registersListeners() {
+ // Skips the test if running on a watch because watches don't have a SliceManager system
+ // service.
+ assumeFalse(isWatch());
+
mController.init();
verify(mTunerService).addTunable(any(TunerService.Tunable.class), anyString());
verify(mConfigurationController).addCallback(
@@ -90,6 +100,10 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase {
@Test
public void onDetachedFromWindow_unregistersListeners() {
+ // Skips the test if running on a watch because watches don't have a SliceManager system
+ // service.
+ assumeFalse(isWatch());
+
ArgumentCaptor<View.OnAttachStateChangeListener> attachListenerArgumentCaptor =
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
@@ -102,4 +116,9 @@ public class KeyguardSliceViewControllerTest extends SysuiTestCase {
verify(mConfigurationController).removeCallback(
any(ConfigurationController.ConfigurationListener.class));
}
+
+ private boolean isWatch() {
+ final PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 2f72cb95db98..419d045885a8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -654,6 +654,24 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void serviceProvidersUpdated_broadcastTriggersInfoRefresh() {
+ // The callback is invoked once on init
+ verify(mTestCallback, times(1)).onRefreshCarrierInfo();
+
+ // WHEN the SERVICE_PROVIDERS_UPDATED broadcast is sent
+ Intent intent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+ intent.putExtra(TelephonyManager.EXTRA_SPN, "spn");
+ intent.putExtra(TelephonyManager.EXTRA_PLMN, "plmn");
+ mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(),
+ putPhoneInfo(intent, null, true));
+ mTestableLooper.processAllMessages();
+
+ // THEN verify keyguardUpdateMonitorCallback receives a refresh callback
+ // Note that we have times(2) here because it's been called once already
+ verify(mTestCallback, times(2)).onRefreshCarrierInfo();
+ }
+
+ @Test
public void testTriesToAuthenticateFingerprint_whenKeyguard() {
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 456702b65091..bdf6bee8ecff 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -18,6 +18,7 @@ package com.android.keyguard;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
+import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
@@ -42,15 +43,12 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
+import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -91,10 +89,9 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
protected @Mock ConfigurationController mConfigurationController;
protected @Mock VibratorHelper mVibrator;
protected @Mock AuthRippleController mAuthRippleController;
- protected @Mock FeatureFlags mFeatureFlags;
protected @Mock KeyguardTransitionRepository mTransitionRepository;
- protected @Mock CommandQueue mCommandQueue;
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
+ protected FakeFeatureFlags mFeatureFlags;
protected LockIconViewController mUnderTest;
@@ -144,6 +141,8 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
+ mFeatureFlags = new FakeFeatureFlags();
+ mFeatureFlags.set(FACE_AUTH_REFACTOR, false);
mUnderTest = new LockIconViewController(
mLockIconView,
mStatusBarStateController,
@@ -160,12 +159,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
mAuthRippleController,
mResources,
new KeyguardTransitionInteractor(mTransitionRepository),
- new KeyguardInteractor(
- new FakeKeyguardRepository(),
- mCommandQueue,
- mFeatureFlags,
- new FakeKeyguardBouncerRepository()
- ),
+ KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(),
mFeatureFlags
);
}
@@ -226,7 +220,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
}
protected void init(boolean useMigrationFlag) {
- when(mFeatureFlags.isEnabled(DOZING_MIGRATION_1)).thenReturn(useMigrationFlag);
+ mFeatureFlags.set(DOZING_MIGRATION_1, useMigrationFlag);
mUnderTest.init();
verify(mLockIconView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index ce96708039ae..b3f9958764dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.accessibility;
+import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
@@ -30,6 +31,7 @@ import static junit.framework.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,6 +39,7 @@ import android.annotation.IdRes;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
+import android.graphics.Rect;
import android.os.UserHandle;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
@@ -49,8 +52,10 @@ import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+import com.android.internal.accessibility.common.MagnificationConstants;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -60,12 +65,13 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@TestableLooper.RunWithLooper
public class WindowMagnificationSettingsTest extends SysuiTestCase {
private static final int MAGNIFICATION_SIZE_SMALL = 1;
@@ -85,6 +91,11 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
private WindowMagnificationSettings mWindowMagnificationSettings;
private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+ private ArgumentCaptor<Float> mSecureSettingsScaleCaptor;
+ private ArgumentCaptor<String> mSecureSettingsNameCaptor;
+ private ArgumentCaptor<Integer> mSecureSettingsUserHandleCaptor;
+ private ArgumentCaptor<Float> mCallbackMagnifierScaleCaptor;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -100,6 +111,10 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
mSecureSettings);
mSettingView = mWindowMagnificationSettings.getSettingView();
+ mSecureSettingsScaleCaptor = ArgumentCaptor.forClass(Float.class);
+ mSecureSettingsNameCaptor = ArgumentCaptor.forClass(String.class);
+ mSecureSettingsUserHandleCaptor = ArgumentCaptor.forClass(Integer.class);
+ mCallbackMagnifierScaleCaptor = ArgumentCaptor.forClass(Float.class);
}
@After
@@ -275,6 +290,39 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
}
@Test
+ public void onScreenSizeChanged_resetPositionToRightBottomCorner() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // move the panel to the center of draggable window bounds
+ mWindowMagnificationSettings.mParams.x =
+ mWindowMagnificationSettings.mDraggableWindowBounds.centerX();
+ mWindowMagnificationSettings.mParams.y =
+ mWindowMagnificationSettings.mDraggableWindowBounds.centerY();
+ mWindowMagnificationSettings.updateButtonViewLayoutIfNeeded();
+
+ final Rect testWindowBounds = new Rect(
+ mWindowManager.getCurrentWindowMetrics().getBounds());
+ testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
+ testWindowBounds.right + 200, testWindowBounds.bottom + 50);
+ mWindowManager.setWindowBounds(testWindowBounds);
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mWindowMagnificationSettings.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
+ });
+
+ // the panel position should be reset to the bottom-right corner
+ assertEquals(
+ mWindowMagnificationSettings.mParams.x,
+ mWindowMagnificationSettings.mDraggableWindowBounds.right);
+ assertEquals(
+ mWindowMagnificationSettings.mParams.y,
+ mWindowMagnificationSettings.mDraggableWindowBounds.bottom);
+ }
+
+ @Test
public void showSettingsPanel_observerRegistered() {
setupMagnificationCapabilityAndMode(
/* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
@@ -289,6 +337,20 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
}
@Test
+ public void showSettingsPanel_observerForMagnificationScaleRegistered() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ verify(mSecureSettings).registerContentObserverForUser(
+ eq(ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE),
+ any(ContentObserver.class),
+ eq(UserHandle.USER_CURRENT));
+ }
+
+ @Test
public void hideSettingsPanel_observerUnregistered() {
setupMagnificationCapabilityAndMode(
/* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
@@ -297,7 +359,162 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
mWindowMagnificationSettings.showSettingPanel();
mWindowMagnificationSettings.hideSettingPanel();
- verify(mSecureSettings).unregisterContentObserver(any(ContentObserver.class));
+ verify(mSecureSettings, times(2)).unregisterContentObserver(any(ContentObserver.class));
+ }
+
+ @Test
+ public void seekbarProgress_justInflated_maxValueAndProgressSetCorrectly() {
+ setupScaleInSecureSettings(0f);
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getMax()).isEqualTo(70);
+ }
+
+ @Test
+ public void seekbarProgress_minMagnification_seekbarProgressIsCorrect() {
+ setupScaleInSecureSettings(0f);
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // Seekbar index from 0 to 70. 1.0f scale (A11Y_SCALE_MIN_VALUE) would correspond to 0.
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
+ }
+
+ @Test
+ public void seekbarProgress_belowMinMagnification_seekbarProgressIsZero() {
+ setupScaleInSecureSettings(0f);
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(0);
+ }
+
+ @Test
+ public void seekbarProgress_magnificationBefore_seekbarProgressIsHalf() {
+ setupScaleInSecureSettings(4f);
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // float scale : from 1.0f to 8.0f, seekbar index from 0 to 70.
+ // 4.0f would correspond to 30.
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(30);
+ }
+
+ @Test
+ public void seekbarProgress_maxMagnificationBefore_seekbarProgressIsMax() {
+ setupScaleInSecureSettings(8f);
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // 8.0f is max magnification {@link MagnificationScaleProvider#MAX_SCALE}.
+ // Max zoom seek bar is 70.
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(70);
+ }
+
+ @Test
+ public void seekbarProgress_aboveMaxMagnificationBefore_seekbarProgressIsMax() {
+ setupScaleInSecureSettings(9f);
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // Max zoom seek bar is 70.
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(70);
+ }
+
+ @Test
+ public void seekbarProgress_progressChangedRoughlyHalf_scaleAndCallbackUpdated() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mWindowMagnificationSettings.showSettingPanel();
+
+ mWindowMagnificationSettings.mZoomSeekbar.setProgress(30);
+
+ verifyScaleUpdatedInSecureSettings(4f);
+ verifyCallbackOnMagnifierScale(4f);
+ }
+
+ @Test
+ public void seekbarProgress_minProgress_callbackUpdated() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mWindowMagnificationSettings.showSettingPanel();
+ // Set progress to non-zero first so onProgressChanged can be triggered upon setting to 0.
+ mWindowMagnificationSettings.mZoomSeekbar.setProgress(30);
+
+ mWindowMagnificationSettings.mZoomSeekbar.setProgress(0);
+
+ // For now, secure settings will not be updated for values < 1.3f. Follow up on this later.
+ verify(mWindowMagnificationSettingsCallback, times(2))
+ .onMagnifierScale(mCallbackMagnifierScaleCaptor.capture());
+ var capturedArgs = mCallbackMagnifierScaleCaptor.getAllValues();
+ assertThat(capturedArgs).hasSize(2);
+ assertThat(capturedArgs.get(1)).isWithin(0.01f).of(1f);
+ }
+
+ @Test
+ public void seekbarProgress_maxProgress_scaleAndCallbackUpdated() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mWindowMagnificationSettings.showSettingPanel();
+
+ mWindowMagnificationSettings.mZoomSeekbar.setProgress(70);
+
+ verifyScaleUpdatedInSecureSettings(8f);
+ verifyCallbackOnMagnifierScale(8f);
+ }
+
+ @Test
+ public void seekbarProgress_scaleUpdatedAfterSettingPanelOpened_progressAlsoUpdated() {
+ setupMagnificationCapabilityAndMode(
+ /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+ /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ var contentObserverCaptor = ArgumentCaptor.forClass(ContentObserver.class);
+ mWindowMagnificationSettings.showSettingPanel();
+ verify(mSecureSettings).registerContentObserverForUser(
+ eq(ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE),
+ contentObserverCaptor.capture(),
+ eq(UserHandle.USER_CURRENT));
+
+ // Simulate outside changes.
+ setupScaleInSecureSettings(4f);
+ // Simulate callback due to outside change.
+ contentObserverCaptor.getValue().onChange(/* selfChange= */ false);
+
+ assertThat(mWindowMagnificationSettings.mZoomSeekbar.getProgress()).isEqualTo(30);
+ }
+
+ private void verifyScaleUpdatedInSecureSettings(float scale) {
+ verify(mSecureSettings).putFloatForUser(
+ mSecureSettingsNameCaptor.capture(),
+ mSecureSettingsScaleCaptor.capture(),
+ mSecureSettingsUserHandleCaptor.capture());
+ assertThat(mSecureSettingsScaleCaptor.getValue()).isWithin(0.01f).of(scale);
+ assertThat(mSecureSettingsNameCaptor.getValue())
+ .isEqualTo(Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE);
+ assertThat(mSecureSettingsUserHandleCaptor.getValue()).isEqualTo(UserHandle.USER_CURRENT);
+ }
+
+ private void verifyCallbackOnMagnifierScale(float scale) {
+ verify(mWindowMagnificationSettingsCallback)
+ .onMagnifierScale(mCallbackMagnifierScaleCaptor.capture());
+ assertThat(mCallbackMagnifierScaleCaptor.getValue()).isWithin(0.01f).of(scale);
}
private <T extends View> T getInternalView(@IdRes int idRes) {
@@ -316,4 +533,11 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase {
ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
UserHandle.USER_CURRENT)).thenReturn(mode);
}
+
+ private void setupScaleInSecureSettings(float scale) {
+ when(mSecureSettings.getFloatForUser(
+ ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ MagnificationConstants.SCALE_MIN_VALUE,
+ UserHandle.USER_CURRENT)).thenReturn(scale);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 1990c8f644b4..3a93e7744d00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.authentication.domain.interactor
+import android.app.admin.DevicePolicyManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.AuthenticationRepository
@@ -48,7 +49,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
fun authMethod() =
testScope.runTest {
val authMethod by collectLastValue(underTest.authenticationMethod)
- assertThat(authMethod).isEqualTo(AuthenticationMethodModel.PIN(1234))
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin(1234))
underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Password("password"))
@@ -147,7 +148,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
val isUnlocked by collectLastValue(underTest.isUnlocked)
- underTest.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(isUnlocked).isFalse()
assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
@@ -160,7 +161,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
testScope.runTest {
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
val isUnlocked by collectLastValue(underTest.isUnlocked)
- underTest.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(isUnlocked).isFalse()
assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
@@ -169,6 +170,51 @@ class AuthenticationInteractorTest : SysuiTestCase() {
}
@Test
+ fun authenticate_withEmptyPin_returnsFalseAndDoesNotUnlockDevice() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf())).isFalse()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(1)
+ }
+
+ @Test
+ fun authenticate_withCorrectMaxLengthPin_returnsTrueAndUnlocksDevice() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(9999999999999999))
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(List(16) { 9 })).isTrue()
+ assertThat(isUnlocked).isTrue()
+ assertThat(failedAttemptCount).isEqualTo(0)
+ }
+
+ @Test
+ fun authenticate_withCorrectTooLongPin_returnsFalseAndDoesNotUnlockDevice() =
+ testScope.runTest {
+ // Max pin length is 16 digits. To avoid issues with overflows, this test ensures
+ // that all pins > 16 decimal digits are rejected.
+
+ // If the policy changes, there is work to do in SysUI.
+ assertThat(DevicePolicyManager.MAX_PASSWORD_LENGTH).isLessThan(17)
+
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Pin(99999999999999999))
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(List(17) { 9 })).isFalse()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(1)
+ }
+
+ @Test
fun authenticate_withCorrectPassword_returnsTrueAndUnlocksDevice() =
testScope.runTest {
val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
index 2d1e8a830fc9..a93af7dd7450 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
@@ -99,7 +99,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
waitForIdleSync()
assertThat(biometricView.isAuthenticated).isTrue()
- verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+ verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED_AND_CONFIRMED)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 40d9009ee81d..2908e753c2fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -64,7 +64,6 @@ import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintA
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
@@ -111,7 +110,6 @@ class SideFpsControllerTest : SysuiTestCase() {
@Mock lateinit var activityTaskManager: ActivityTaskManager
@Mock lateinit var sideFpsView: View
@Mock lateinit var displayManager: DisplayManager
- @Mock lateinit var overviewProxyService: OverviewProxyService
@Mock lateinit var handler: Handler
@Mock lateinit var dumpManager: DumpManager
@Captor lateinit var overlayCaptor: ArgumentCaptor<View>
@@ -262,7 +260,6 @@ class SideFpsControllerTest : SysuiTestCase() {
fingerprintManager,
windowManager,
activityTaskManager,
- overviewProxyService,
displayManager,
displayStateInteractor,
executor,
@@ -686,18 +683,6 @@ class SideFpsControllerTest : SysuiTestCase() {
verify(windowManager).removeView(any())
}
- private fun hidesWithTaskbar(visible: Boolean) {
- overlayController.show(SENSOR_ID, REASON_UNKNOWN)
- executor.runAllReady()
-
- sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(true, false)
- executor.runAllReady()
-
- verify(windowManager).addView(any(), any())
- verify(windowManager, never()).removeView(any())
- verify(sideFpsView).visibility = if (visible) View.VISIBLE else View.GONE
- }
-
/**
* {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
* and uses RotateUtils.rotateBounds to map to the correct indicator location given the device
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 9f5c181c3129..6a63c32f2c40 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -69,7 +69,7 @@ class BouncerInteractorTest : SysuiTestCase() {
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
val message by collectLastValue(underTest.message)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
underTest.showOrUnlockDevice("container1")
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -82,7 +82,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
// Wrong input.
- underTest.authenticate(listOf(9, 8, 7))
+ assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -90,7 +90,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
// Correct input.
- underTest.authenticate(listOf(1, 2, 3, 4))
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -114,7 +114,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
// Wrong input.
- underTest.authenticate("alohamora".toList())
+ assertThat(underTest.authenticate("alohamora".toList())).isFalse()
assertThat(message).isEqualTo(MESSAGE_WRONG_PASSWORD)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -122,7 +122,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
// Correct input.
- underTest.authenticate("password".toList())
+ assertThat(underTest.authenticate("password".toList())).isTrue()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -146,9 +146,12 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
// Wrong input.
- underTest.authenticate(
- listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(3, 4))
- )
+ assertThat(
+ underTest.authenticate(
+ listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(3, 4))
+ )
+ )
+ .isFalse()
assertThat(message).isEqualTo(MESSAGE_WRONG_PATTERN)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -156,7 +159,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
// Correct input.
- underTest.authenticate(emptyList())
+ assertThat(underTest.authenticate(emptyList())).isTrue()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -164,7 +167,7 @@ class BouncerInteractorTest : SysuiTestCase() {
fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
runCurrent()
@@ -208,13 +211,13 @@ class BouncerInteractorTest : SysuiTestCase() {
val throttling by collectLastValue(underTest.throttling)
val message by collectLastValue(underTest.message)
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(throttling).isNull()
assertThat(message).isEqualTo("")
assertThat(isUnlocked).isFalse()
repeat(BouncerInteractor.THROTTLE_EVERY) { times ->
// Wrong PIN.
- underTest.authenticate(listOf(6, 7, 8, 9))
+ assertThat(underTest.authenticate(listOf(6, 7, 8, 9))).isFalse()
if (times < BouncerInteractor.THROTTLE_EVERY - 1) {
assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
}
@@ -223,7 +226,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
// Correct PIN, but throttled, so doesn't unlock:
- underTest.authenticate(listOf(1, 2, 3, 4))
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isFalse()
assertThat(isUnlocked).isFalse()
assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
@@ -241,7 +244,7 @@ class BouncerInteractorTest : SysuiTestCase() {
assertThat(isUnlocked).isFalse()
// Correct PIN and no longer throttled so unlocks:
- underTest.authenticate(listOf(1, 2, 3, 4))
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
assertThat(isUnlocked).isTrue()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
new file mode 100644
index 000000000000..b53e03419df3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class AuthMethodBouncerViewModelTest : SysuiTestCase() {
+
+ private val testScope = TestScope()
+ private val utils = SceneTestUtils(this, testScope)
+ private val authenticationInteractor =
+ utils.authenticationInteractor(
+ utils.authenticationRepository(),
+ )
+ private val underTest =
+ PinBouncerViewModel(
+ applicationScope = testScope.backgroundScope,
+ interactor =
+ utils.bouncerInteractor(
+ authenticationInteractor = authenticationInteractor,
+ sceneInteractor = utils.sceneInteractor(),
+ ),
+ isInputEnabled = MutableStateFlow(true),
+ )
+
+ @Test
+ fun animateFailure() =
+ testScope.runTest {
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
+ val animateFailure by collectLastValue(underTest.animateFailure)
+ assertThat(animateFailure).isFalse()
+
+ // Wrong PIN:
+ underTest.onPinButtonClicked(3)
+ underTest.onPinButtonClicked(4)
+ underTest.onPinButtonClicked(5)
+ underTest.onPinButtonClicked(6)
+ underTest.onAuthenticateButtonClicked()
+ assertThat(animateFailure).isTrue()
+
+ underTest.onFailureAnimationShown()
+ assertThat(animateFailure).isFalse()
+
+ // Correct PIN:
+ underTest.onPinButtonClicked(1)
+ underTest.onPinButtonClicked(2)
+ underTest.onPinButtonClicked(3)
+ underTest.onPinButtonClicked(4)
+ underTest.onAuthenticateButtonClicked()
+ assertThat(animateFailure).isFalse()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index b942ccbb51f3..c6074962ee8e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -93,22 +93,21 @@ class BouncerViewModelTest : SysuiTestCase() {
}
@Test
- fun isMessageUpdateAnimationsEnabled() =
+ fun message() =
testScope.runTest {
- val isMessageUpdateAnimationsEnabled by
- collectLastValue(underTest.isMessageUpdateAnimationsEnabled)
+ val message by collectLastValue(underTest.message)
val throttling by collectLastValue(bouncerInteractor.throttling)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
- assertThat(isMessageUpdateAnimationsEnabled).isTrue()
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
+ assertThat(message?.isUpdateAnimated).isTrue()
repeat(BouncerInteractor.THROTTLE_EVERY) {
// Wrong PIN.
bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
}
- assertThat(isMessageUpdateAnimationsEnabled).isFalse()
+ assertThat(message?.isUpdateAnimated).isFalse()
throttling?.totalDurationSec?.let { seconds -> advanceTimeBy(seconds * 1000L) }
- assertThat(isMessageUpdateAnimationsEnabled).isTrue()
+ assertThat(message?.isUpdateAnimated).isTrue()
}
@Test
@@ -121,7 +120,7 @@ class BouncerViewModelTest : SysuiTestCase() {
}
)
val throttling by collectLastValue(bouncerInteractor.throttling)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(isInputEnabled).isTrue()
repeat(BouncerInteractor.THROTTLE_EVERY) {
@@ -138,7 +137,7 @@ class BouncerViewModelTest : SysuiTestCase() {
fun throttlingDialogMessage() =
testScope.runTest {
val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
repeat(BouncerInteractor.THROTTLE_EVERY) {
// Wrong PIN.
@@ -155,7 +154,7 @@ class BouncerViewModelTest : SysuiTestCase() {
return listOf(
AuthenticationMethodModel.None,
AuthenticationMethodModel.Swipe,
- AuthenticationMethodModel.PIN(1234),
+ AuthenticationMethodModel.Pin(1234),
AuthenticationMethodModel.Password("password"),
AuthenticationMethodModel.Pattern(
listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index b7b90de3b54a..f436aa309ac5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -85,7 +85,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
underTest.onShown()
- assertThat(message).isEqualTo(ENTER_YOUR_PASSWORD)
+ assertThat(message?.text).isEqualTo(ENTER_YOUR_PASSWORD)
assertThat(password).isEqualTo("")
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -109,7 +109,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
underTest.onPasswordInputChanged("password")
- assertThat(message).isEmpty()
+ assertThat(message?.text).isEmpty()
assertThat(password).isEqualTo("password")
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -156,7 +156,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
underTest.onAuthenticateKeyPressed()
assertThat(password).isEqualTo("")
- assertThat(message).isEqualTo(WRONG_PASSWORD)
+ assertThat(message?.text).isEqualTo(WRONG_PASSWORD)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -179,13 +179,13 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
underTest.onPasswordInputChanged("wrong")
underTest.onAuthenticateKeyPressed()
assertThat(password).isEqualTo("")
- assertThat(message).isEqualTo(WRONG_PASSWORD)
+ assertThat(message?.text).isEqualTo(WRONG_PASSWORD)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
// Enter the correct password:
underTest.onPasswordInputChanged("password")
- assertThat(message).isEmpty()
+ assertThat(message?.text).isEmpty()
underTest.onAuthenticateKeyPressed()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index b588ba2b2574..d7d7154705ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -89,7 +89,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
underTest.onShown()
- assertThat(message).isEqualTo(ENTER_YOUR_PATTERN)
+ assertThat(message?.text).isEqualTo(ENTER_YOUR_PATTERN)
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
assertThat(isUnlocked).isFalse()
@@ -115,7 +115,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
underTest.onDragStart()
- assertThat(message).isEmpty()
+ assertThat(message?.text).isEmpty()
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
assertThat(isUnlocked).isFalse()
@@ -202,7 +202,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
- assertThat(message).isEqualTo(WRONG_PATTERN)
+ assertThat(message?.text).isEqualTo(WRONG_PATTERN)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -235,7 +235,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
underTest.onDragEnd()
assertThat(selectedDots).isEmpty()
assertThat(currentDot).isNull()
- assertThat(message).isEqualTo(WRONG_PATTERN)
+ assertThat(message?.text).isEqualTo(WRONG_PATTERN)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 83f9687d7ac5..7b6bb37459a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -25,12 +25,12 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Correspondence
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -85,8 +85,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -94,8 +94,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onShown()
- assertThat(message).isEqualTo(ENTER_YOUR_PIN)
- assertThat(pinLengths).isEqualTo(0 to 0)
+ assertThat(message?.text).isEqualTo(ENTER_YOUR_PIN)
+ assertThat(entries).hasSize(0)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -106,8 +106,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -116,8 +116,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onPinButtonClicked(1)
- assertThat(message).isEmpty()
- assertThat(pinLengths).isEqualTo(0 to 1)
+ assertThat(message?.text).isEmpty()
+ assertThat(entries).hasSize(1)
+ assertThat(entries?.map { it.input }).containsExactly(1)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -128,32 +129,59 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPinButtonClicked(1)
- assertThat(pinLengths).isEqualTo(0 to 1)
+ assertThat(entries).hasSize(1)
underTest.onBackspaceButtonClicked()
- assertThat(message).isEmpty()
- assertThat(pinLengths).isEqualTo(1 to 0)
+ assertThat(message?.text).isEmpty()
+ assertThat(entries).hasSize(0)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@Test
+ fun onPinEdit() =
+ testScope.runTest {
+ val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+ val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+ val message by collectLastValue(bouncerViewModel.message)
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
+ authenticationInteractor.lockDevice()
+ sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ underTest.onShown()
+
+ underTest.onPinButtonClicked(1)
+ underTest.onPinButtonClicked(2)
+ underTest.onPinButtonClicked(3)
+ underTest.onBackspaceButtonClicked()
+ underTest.onBackspaceButtonClicked()
+ underTest.onPinButtonClicked(4)
+ underTest.onPinButtonClicked(5)
+
+ assertThat(entries).hasSize(3)
+ assertThat(entries?.map { it.input }).containsExactly(1, 4, 5).inOrder()
+ assertThat(entries?.map { it.sequenceNumber }).isInStrictOrder()
+ }
+
+ @Test
fun onBackspaceButtonLongPressed() =
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -165,13 +193,9 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onPinButtonClicked(4)
underTest.onBackspaceButtonLongPressed()
- repeat(4) { index ->
- assertThat(pinLengths).isEqualTo(4 - index to 3 - index)
- advanceTimeBy(PinBouncerViewModel.BACKSPACE_LONG_PRESS_DELAY_MS)
- }
- assertThat(message).isEmpty()
- assertThat(pinLengths).isEqualTo(1 to 0)
+ assertThat(message?.text).isEmpty()
+ assertThat(entries).hasSize(0)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -181,7 +205,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -204,8 +228,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -219,8 +243,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onAuthenticateButtonClicked()
- assertThat(pinLengths).isEqualTo(0 to 0)
- assertThat(message).isEqualTo(WRONG_PIN)
+ assertThat(entries).hasSize(0)
+ assertThat(message?.text).isEqualTo(WRONG_PIN)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
}
@@ -231,8 +255,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
val message by collectLastValue(bouncerViewModel.message)
- val pinLengths by collectLastValue(underTest.pinLengths)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
assertThat(isUnlocked).isFalse()
@@ -244,8 +268,8 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onPinButtonClicked(4)
underTest.onPinButtonClicked(5) // PIN is now wrong!
underTest.onAuthenticateButtonClicked()
- assertThat(message).isEqualTo(WRONG_PIN)
- assertThat(pinLengths).isEqualTo(0 to 0)
+ assertThat(message?.text).isEqualTo(WRONG_PIN)
+ assertThat(entries).hasSize(0)
assertThat(isUnlocked).isFalse()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
@@ -254,7 +278,7 @@ class PinBouncerViewModelTest : SysuiTestCase() {
underTest.onPinButtonClicked(2)
underTest.onPinButtonClicked(3)
underTest.onPinButtonClicked(4)
- assertThat(message).isEmpty()
+ assertThat(message?.text).isEmpty()
underTest.onAuthenticateButtonClicked()
@@ -266,5 +290,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
private const val CONTAINER_NAME = "container1"
private const val ENTER_YOUR_PIN = "Enter your pin"
private const val WRONG_PIN = "Wrong pin"
+
+ val KEY_CODE =
+ Correspondence.transforming<EnteredKey, Int>(
+ { it?.input },
+ "has a eventId of",
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
index ca6282c66a17..461ec653d819 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
@@ -28,6 +28,7 @@ import androidx.lifecycle.Observer;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.DreamLogger;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.Flags;
@@ -56,6 +57,8 @@ public class ComplicationCollectionLiveDataTest extends SysuiTestCase {
private FakeFeatureFlags mFeatureFlags;
@Mock
private Observer mObserver;
+ @Mock
+ private DreamLogger mLogger;
@Before
public void setUp() {
@@ -66,7 +69,8 @@ public class ComplicationCollectionLiveDataTest extends SysuiTestCase {
mStateController = new DreamOverlayStateController(
mExecutor,
/* overlayEnabled= */ true,
- mFeatureFlags);
+ mFeatureFlags,
+ mLogger);
mLiveData = new ComplicationCollectionLiveData(mStateController);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
index 10bfc1b292d3..ee213f7c4257 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.APP_PANELS_ALL_APPS_ALLOWED
import com.android.systemui.flags.Flags.USE_APP_PANELS
import com.android.systemui.settings.UserTracker
+import com.android.systemui.util.ActivityTaskManagerProxy
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argThat
@@ -88,6 +89,8 @@ class ControlsListingControllerImplTest : SysuiTestCase() {
private lateinit var packageManager: PackageManager
@Mock
private lateinit var featureFlags: FeatureFlags
+ @Mock
+ private lateinit var activityTaskManagerProxy: ActivityTaskManagerProxy
private var componentName = ComponentName("pkg", "class1")
private var activityName = ComponentName("pkg", "activity")
@@ -112,6 +115,7 @@ class ControlsListingControllerImplTest : SysuiTestCase() {
// Return disabled by default
`when`(packageManager.getComponentEnabledSetting(any()))
.thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED)
+ `when`(activityTaskManagerProxy.supportsMultiWindow(any())).thenReturn(true)
mContext.setMockPackageManager(packageManager)
mContext.orCreateTestableResources
@@ -136,6 +140,7 @@ class ControlsListingControllerImplTest : SysuiTestCase() {
executor,
{ mockSL },
userTracker,
+ activityTaskManagerProxy,
dumpManager,
featureFlags
)
@@ -171,6 +176,7 @@ class ControlsListingControllerImplTest : SysuiTestCase() {
exec,
{ mockServiceListing },
userTracker,
+ activityTaskManagerProxy,
dumpManager,
featureFlags
)
@@ -637,7 +643,34 @@ class ControlsListingControllerImplTest : SysuiTestCase() {
assertThat(services[0].serviceInfo.componentName).isEqualTo(componentName)
}
+ @Test
+ fun testNoPanelIfMultiWindowNotSupported() {
+ `when`(activityTaskManagerProxy.supportsMultiWindow(any())).thenReturn(false)
+
+ val serviceInfo = ServiceInfo(
+ componentName,
+ activityName
+ )
+
+ `when`(packageManager.getComponentEnabledSetting(eq(activityName)))
+ .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)
+
+ setUpQueryResult(listOf(
+ ActivityInfo(
+ activityName,
+ enabled = true,
+ exported = true,
+ permission = Manifest.permission.BIND_CONTROLS
+ )
+ ))
+
+ val list = listOf(serviceInfo)
+ serviceListingCallbackCaptor.value.onServicesReloaded(list)
+ executor.runAllReady()
+
+ assertNull(controller.getCurrentServices()[0].panelActivity)
+ }
private fun ServiceInfo(
componentName: ComponentName,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
index b2e37ccb045b..4ba67182c32c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
@@ -145,7 +145,7 @@ class ControlsProviderSelectorActivityTest : SysuiTestCase() {
assertThat(activityRule.activity.lastStartedActivity?.component?.className)
.isEqualTo(ControlsFavoritingActivity::class.java.name)
- assertThat(activityRule.activity.triedToFinish).isTrue()
+ assertThat(activityRule.activity.triedToFinish).isFalse()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 7b4160551c82..2c1ebe4121af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -58,6 +58,9 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Mock
private FeatureFlags mFeatureFlags;
+ @Mock
+ private DreamLogger mLogger;
+
final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
@Before
@@ -405,6 +408,6 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
}
private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) {
- return new DreamOverlayStateController(mExecutor, overlayEnabled, mFeatureFlags);
+ return new DreamOverlayStateController(mExecutor, overlayEnabled, mFeatureFlags, mLogger);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index d16b7570e2c3..5dc0e55632fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -113,6 +113,8 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
DreamOverlayStateController mDreamOverlayStateController;
@Mock
UserTracker mUserTracker;
+ @Mock
+ DreamLogger mLogger;
@Captor
private ArgumentCaptor<DreamOverlayStateController.Callback> mCallbackCaptor;
@@ -146,7 +148,8 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
mStatusBarWindowStateController,
mDreamOverlayStatusBarItemsProvider,
mDreamOverlayStateController,
- mUserTracker);
+ mUserTracker,
+ mLogger);
}
@Test
@@ -289,7 +292,8 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
mStatusBarWindowStateController,
mDreamOverlayStatusBarItemsProvider,
mDreamOverlayStateController,
- mUserTracker);
+ mUserTracker,
+ mLogger);
controller.onViewAttached();
verify(mView, never()).showIcon(
eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 8ee7d3e86265..c9470bb41ba5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -34,6 +34,7 @@ import com.android.systemui.R
import com.android.systemui.SystemUIAppComponentFactoryBase
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.dock.DockManagerFake
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
@@ -185,6 +186,7 @@ class CustomizationProviderTest : SysuiTestCase() {
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
+ configurationRepository = FakeConfigurationRepository(),
),
registry = mock(),
lockPatternUtils = lockPatternUtils,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index 688c2db044e4..477e076669b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -10,6 +10,7 @@ import android.testing.TestableLooper.RunWithLooper
import android.view.RemoteAnimationTarget
import android.view.SurfaceControl
import android.view.SyncRtSurfaceTransactionApplier
+import android.view.View
import android.view.ViewRootImpl
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardViewController
@@ -32,6 +33,7 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@@ -374,6 +376,83 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
verifyNoMoreInteractions(surfaceTransactionApplier)
}
+ @Test
+ fun unlockToLauncherWithInWindowAnimations_ssViewIsVisible() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.VISIBLE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+ verify(mockLockscreenSmartspaceView).visibility = View.INVISIBLE
+ }
+
+ @Test
+ fun unlockToLauncherWithInWindowAnimations_ssViewIsInvisible() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+ verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE
+ }
+
+ @Test
+ fun unlockToLauncherWithInWindowAnimations_ssViewIsGone() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+ verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE
+ }
+
+ @Test
+ fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsTrue() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
+
+ verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE
+ }
+
+ @Test
+ fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsTrue() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
+
+ verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE
+ }
+
+ @Test
+ fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsFalse() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false)
+
+ verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE
+ }
+
+ @Test
+ fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsFalse() {
+ val mockLockscreenSmartspaceView = mock(View::class.java)
+ whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+ keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+ keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false)
+
+ verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE
+ }
+
private class ArgThatCaptor<T> {
private var allArgs: MutableList<T> = mutableListOf()
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 f31ac00051f6..c4a0e7c6b7ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -16,11 +16,16 @@
package com.android.systemui.keyguard;
+import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION;
+import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
+import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT;
import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
+import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
+import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -35,9 +40,12 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.AlarmManager;
import android.app.IActivityManager;
+import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.telephony.TelephonyManager;
@@ -94,9 +102,12 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.settings.SystemSettings;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.wm.shell.keyguard.KeyguardTransitions;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -156,18 +167,24 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock CentralSurfaces mCentralSurfaces;
private @Mock UiEventLogger mUiEventLogger;
private @Mock SessionTracker mSessionTracker;
+ private @Mock SystemSettings mSystemSettings;
+ private @Mock SecureSettings mSecureSettings;
+ private @Mock AlarmManager mAlarmManager;
+ private FakeSystemClock mSystemClock;
private FakeFeatureFlags mFeatureFlags;
+ private int mInitialUserId;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mFalsingCollector = new FalsingCollectorFake();
-
+ mSystemClock = new FakeSystemClock();
when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class));
when(mInteractionJankMonitor.begin(any(), anyInt())).thenReturn(true);
when(mInteractionJankMonitor.end(anyInt())).thenReturn(true);
+ mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
final ViewRootImpl testViewRoot = mock(ViewRootImpl.class);
when(testViewRoot.getView()).thenReturn(mock(View.class));
when(mStatusBarKeyguardViewManager.getViewRootImpl()).thenReturn(testViewRoot);
@@ -183,6 +200,12 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
DejankUtils.setImmediate(true);
createAndStartViewMediator();
+ mInitialUserId = KeyguardUpdateMonitor.getCurrentUser();
+ }
+
+ @After
+ public void teardown() {
+ KeyguardUpdateMonitor.setCurrentUser(mInitialUserId);
}
@Test
@@ -369,6 +392,49 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
}
@Test
+ public void lockAfterScreenTimeoutUsesValueFromSettings() {
+ int currentUserId = 99;
+ int userSpecificTimeout = 5999;
+ KeyguardUpdateMonitor.setCurrentUser(currentUserId);
+
+ when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
+ when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L);
+ when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout);
+ mSystemClock.setElapsedRealtime(0L);
+ ArgumentCaptor<PendingIntent> pendingIntent = ArgumentCaptor.forClass(PendingIntent.class);
+
+ mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_TIMEOUT);
+
+ verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture());
+ assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction());
+ }
+
+ @Test
+ public void lockAfterSpecifiedAfterDreamStarted() {
+ int currentUserId = 99;
+ int userSpecificTimeout = 5999;
+ KeyguardUpdateMonitor.setCurrentUser(currentUserId);
+
+ // set mDeviceInteractive to true
+ mViewMediator.onStartedWakingUp(WAKE_REASON_WAKE_MOTION, false);
+ mFeatureFlags.set(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING, false);
+ when(mLockPatternUtils.isSecure(currentUserId)).thenReturn(true);
+ when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L);
+ when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout);
+ mSystemClock.setElapsedRealtime(0L);
+ ArgumentCaptor<PendingIntent> pendingIntent = ArgumentCaptor.forClass(PendingIntent.class);
+
+ mViewMediator.onDreamingStarted();
+
+ verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture());
+ assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction());
+ }
+
+ @Test
public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() {
mViewMediator.hideSurfaceBehindKeyguard();
@@ -629,7 +695,10 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
() -> mNotificationShadeWindowController,
() -> mActivityLaunchAnimator,
() -> mScrimController,
- mFeatureFlags);
+ mFeatureFlags,
+ mSecureSettings,
+ mSystemSettings,
+ mSystemClock);
mViewMediator.start();
mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index 548d26f2aaed..eb970221388b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -7,11 +7,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeCommandQueue
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -60,13 +58,12 @@ class ResourceTrimmerTest : SysuiTestCase() {
keyguardRepository.setDozeAmount(0f)
keyguardRepository.setKeyguardGoingAway(false)
- val keyguardInteractor =
- KeyguardInteractor(
- keyguardRepository,
- FakeCommandQueue(),
- featureFlags,
- FakeKeyguardBouncerRepository()
+ val withDeps =
+ KeyguardInteractorFactory.create(
+ repository = keyguardRepository,
+ featureFlags = featureFlags,
)
+ val keyguardInteractor = withDeps.keyguardInteractor
resourceTrimmer =
ResourceTrimmer(
keyguardInteractor,
@@ -98,7 +95,8 @@ class ResourceTrimmerTest : SysuiTestCase() {
)
testScope.runCurrent()
verify(globalWindowManager, times(1))
- .trimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND)
+ .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+ verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
}
@Test
@@ -115,7 +113,8 @@ class ResourceTrimmerTest : SysuiTestCase() {
)
testScope.runCurrent()
verify(globalWindowManager, times(1))
- .trimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND)
+ .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+ verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
}
@Test
@@ -161,7 +160,8 @@ class ResourceTrimmerTest : SysuiTestCase() {
keyguardRepository.setDozeAmount(1f)
testScope.runCurrent()
verify(globalWindowManager, times(1))
- .trimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND)
+ .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+ verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
index 13d1e6488d25..c85c7f678536 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
@@ -28,7 +28,7 @@ import kotlinx.coroutines.yield
@RoboPilotTest
class FakeKeyguardQuickAffordanceConfig(
override val key: String,
- override val pickerName: String = key,
+ private val pickerName: String = key,
override val pickerIconResourceId: Int = 0,
) : KeyguardQuickAffordanceConfig {
@@ -41,6 +41,8 @@ class FakeKeyguardQuickAffordanceConfig(
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
_lockScreenState
+ override fun pickerName(): String = pickerName
+
override fun onTriggered(
expandable: Expandable?,
): OnTriggeredResult {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 9200d7219948..de3bb6f3d031 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -72,6 +72,8 @@ class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
val resources: Resources = mock()
whenever(resources.getStringArray(R.array.config_keyguardQuickAffordanceDefaults))
.thenReturn(emptyArray())
+ whenever(resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled))
+ .thenReturn(true)
whenever(context.resources).thenReturn(resources)
testDispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index bad4b360ce07..b2528c5b9832 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -66,6 +66,7 @@ class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
sharedPrefs = mutableMapOf()
whenever(userFileManager.getSharedPreferences(anyString(), anyInt(), anyInt())).thenAnswer {
val userId = it.arguments[2] as Int
@@ -86,6 +87,13 @@ class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
@After
fun tearDown() {
+ mContext
+ .getOrCreateTestableResources()
+ .removeOverride(R.bool.custom_lockscreen_shortcuts_enabled)
+ mContext
+ .getOrCreateTestableResources()
+ .removeOverride(R.array.config_keyguardQuickAffordanceDefaults)
+
Dispatchers.resetMain()
}
@@ -358,6 +366,22 @@ class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
job.cancel()
}
+ @Test
+ fun getSelections_alwaysReturnsDefaultsIfCustomShortcutsFeatureDisabled() {
+ overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, false)
+ overrideResource(
+ R.array.config_keyguardQuickAffordanceDefaults,
+ arrayOf("leftTest:testShortcut1", "rightTest:testShortcut2")
+ )
+
+ assertThat(underTest.getSelections()).isEqualTo(
+ mapOf(
+ "leftTest" to listOf("testShortcut1"),
+ "rightTest" to listOf("testShortcut2"),
+ )
+ )
+ }
+
private fun assertSelections(
observed: Map<String, List<String>>?,
expected: Map<String, List<String>>,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index e61620beeff3..3ea74e582229 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -47,6 +47,7 @@ import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AuthenticationStatus
import com.android.systemui.keyguard.shared.model.DetectionStatus
@@ -159,17 +160,16 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
biometricSettingsRepository = FakeBiometricSettingsRepository()
deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
trustRepository = FakeTrustRepository()
- keyguardRepository = FakeKeyguardRepository()
- bouncerRepository = FakeKeyguardBouncerRepository()
featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
- fakeCommandQueue = FakeCommandQueue()
- keyguardInteractor =
- KeyguardInteractor(
- keyguardRepository,
- fakeCommandQueue,
- featureFlags,
- bouncerRepository
+ val withDeps =
+ KeyguardInteractorFactory.create(
+ featureFlags = featureFlags,
)
+ keyguardInteractor = withDeps.keyguardInteractor
+ keyguardRepository = withDeps.repository
+ bouncerRepository = withDeps.bouncerRepository
+ fakeCommandQueue = withDeps.commandQueue
+
alternateBouncerInteractor =
AlternateBouncerInteractor(
bouncerRepository = bouncerRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 8dc04bd73b8e..6b5be58b6d03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -47,6 +47,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
+import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -70,6 +71,7 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
@Before
fun setUp() {
+ overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
context.resources.configuration.setLayoutDirection(Locale.US)
config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
@@ -137,6 +139,13 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
)
}
+ @After
+ fun tearDown() {
+ mContext
+ .getOrCreateTestableResources()
+ .removeOverride(R.bool.custom_lockscreen_shortcuts_enabled)
+ }
+
@Test
fun setSelections() =
testScope.runTest {
@@ -180,12 +189,12 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = config1.key,
- name = config1.pickerName,
+ name = config1.pickerName(),
iconResourceId = config1.pickerIconResourceId,
),
KeyguardQuickAffordancePickerRepresentation(
id = config2.key,
- name = config2.pickerName,
+ name = config2.pickerName(),
iconResourceId = config2.pickerIconResourceId,
),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 4b797cb1ba46..953d61844596 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -97,7 +97,8 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
dozeParameters,
authController,
dreamOverlayCallbackController,
- mainDispatcher
+ mainDispatcher,
+ testScope.backgroundScope,
)
}
@@ -343,8 +344,6 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
)
job.cancel()
- runCurrent()
- verify(wakefulnessLifecycle).removeObserver(captor.value)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index 0d695aa231cc..a4f19b415061 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -22,6 +22,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
@@ -50,6 +51,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
private lateinit var underTest: KeyguardInteractor
private lateinit var repository: FakeKeyguardRepository
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
+ private lateinit var configurationRepository: FakeConfigurationRepository
@Before
fun setUp() {
@@ -59,12 +61,14 @@ class KeyguardInteractorTest : SysuiTestCase() {
testScope = TestScope()
repository = FakeKeyguardRepository()
bouncerRepository = FakeKeyguardBouncerRepository()
+ configurationRepository = FakeConfigurationRepository()
underTest =
KeyguardInteractor(
repository,
commandQueue,
featureFlags,
bouncerRepository,
+ configurationRepository,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index fb21847cd4d1..8f6bbc9d48d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -38,8 +38,6 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
@@ -48,7 +46,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any
@@ -225,7 +222,6 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
@Mock private lateinit var expandable: Expandable
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@@ -309,12 +305,10 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
underTest =
KeyguardQuickAffordanceInteractor(
keyguardInteractor =
- KeyguardInteractor(
- repository = FakeKeyguardRepository(),
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- ),
+ KeyguardInteractorFactory.create(
+ featureFlags = featureFlags,
+ )
+ .keyguardInteractor,
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
@@ -368,11 +362,11 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
}
- underTest.onQuickAffordanceTriggered(
- configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
- expandable = expandable,
- slotId = "",
- )
+ underTest.onQuickAffordanceTriggered(
+ configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
+ expandable = expandable,
+ slotId = "",
+ )
if (startActivity) {
if (needsToUnlockFirst) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 5d2c3edd40af..a087c351d90f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -40,7 +40,6 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
@@ -53,7 +52,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.mock
@@ -84,7 +82,6 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@@ -102,6 +99,8 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
+ overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
+
repository = FakeKeyguardRepository()
repository.setKeyguardShowing(true)
@@ -166,15 +165,14 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
set(Flags.FACE_AUTH_REFACTOR, true)
}
+ val withDeps =
+ KeyguardInteractorFactory.create(
+ featureFlags = featureFlags,
+ repository = repository,
+ )
underTest =
KeyguardQuickAffordanceInteractor(
- keyguardInteractor =
- KeyguardInteractor(
- repository = repository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- ),
+ keyguardInteractor = withDeps.keyguardInteractor,
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
@@ -200,7 +198,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
devicePolicyManager = devicePolicyManager,
dockManager = dockManager,
backgroundDispatcher = testDispatcher,
- appContext = mContext,
+ appContext = context,
)
}
@@ -433,7 +431,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = homeControls.key,
- name = homeControls.pickerName,
+ name = homeControls.pickerName(),
iconResourceId = homeControls.pickerIconResourceId,
),
),
@@ -467,7 +465,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -504,7 +502,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -512,7 +510,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = qrCodeScanner.key,
- name = qrCodeScanner.pickerName,
+ name = qrCodeScanner.pickerName(),
iconResourceId = qrCodeScanner.pickerIconResourceId,
),
),
@@ -568,7 +566,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -663,7 +661,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 603f199b468b..c53d4305f226 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -21,7 +21,6 @@ import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -39,7 +38,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
@@ -74,10 +72,10 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var shadeRepository: ShadeRepository
private lateinit var transitionRepository: FakeKeyguardTransitionRepository
+ private lateinit var featureFlags: FakeFeatureFlags
// Used to verify transition requests for test output
@Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
@@ -103,11 +101,11 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(PIN)
- val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
+ featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
fromLockscreenTransitionInteractor =
FromLockscreenTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
shadeRepository = shadeRepository,
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -117,7 +115,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDreamingTransitionInteractor =
FromDreamingTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -126,7 +124,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromAodTransitionInteractor =
FromAodTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -135,7 +133,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromGoneTransitionInteractor =
FromGoneTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -144,7 +142,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDozingTransitionInteractor =
FromDozingTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -153,7 +151,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromOccludedTransitionInteractor =
FromOccludedTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -162,7 +160,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromAlternateBouncerTransitionInteractor =
FromAlternateBouncerTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -171,7 +169,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromPrimaryBouncerTransitionInteractor =
FromPrimaryBouncerTransitionInteractor(
scope = testScope,
- keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
keyguardSecurityModel = keyguardSecurityModel,
@@ -882,13 +880,13 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
WakeSleepReason.OTHER
)
- private fun createKeyguardInteractor(featureFlags: FeatureFlags): KeyguardInteractor {
- return KeyguardInteractor(
- keyguardRepository,
- commandQueue,
- featureFlags,
- bouncerRepository,
- )
+ private fun createKeyguardInteractor(): KeyguardInteractor {
+ return KeyguardInteractorFactory.create(
+ featureFlags = featureFlags,
+ repository = keyguardRepository,
+ bouncerRepository = bouncerRepository,
+ )
+ .keyguardInteractor
}
private suspend fun TestScope.runTransition(from: KeyguardState, to: KeyguardState) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
index d622f1c30816..65781c497944 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
@@ -95,7 +95,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.lockDevice()
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.dismissLockscreen()
@@ -108,7 +108,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
authenticationInteractor.unlockDevice()
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.dismissLockscreen()
@@ -195,7 +195,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
assertThat(isUnlocked).isFalse()
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 8a36dbc86e81..a493b1ddb93d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -39,12 +39,11 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -56,7 +55,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
@@ -95,7 +93,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -140,7 +137,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
),
),
)
- repository = FakeKeyguardRepository()
val featureFlags =
FakeFeatureFlags().apply {
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
@@ -149,13 +145,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, false)
}
- val keyguardInteractor =
- KeyguardInteractor(
- repository = repository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- )
+ val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ val keyguardInteractor = withDeps.keyguardInteractor
+ repository = withDeps.repository
+
whenever(userTracker.userHandle).thenReturn(mock())
whenever(userTracker.userId).thenReturn(10)
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
@@ -550,91 +543,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
}
@Test
- fun isIndicationAreaPadded() =
- testScope.runTest {
- repository.setKeyguardShowing(true)
- val value = collectLastValue(underTest.isIndicationAreaPadded)
-
- assertThat(value()).isFalse()
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = true,
- slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
- )
- )
- assertThat(value()).isTrue()
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_END,
- testConfig =
- TestConfig(
- isVisible = true,
- isClickable = true,
- icon = mock(),
- canShowWhileLocked = false,
- slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(),
- )
- )
- assertThat(value()).isTrue()
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_START,
- testConfig =
- TestConfig(
- isVisible = false,
- slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
- )
- )
- assertThat(value()).isTrue()
- setUpQuickAffordanceModel(
- position = KeyguardQuickAffordancePosition.BOTTOM_END,
- testConfig =
- TestConfig(
- isVisible = false,
- slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(),
- )
- )
- assertThat(value()).isFalse()
- }
-
- @Test
- fun indicationAreaTranslationX() =
- testScope.runTest {
- val value = collectLastValue(underTest.indicationAreaTranslationX)
-
- assertThat(value()).isEqualTo(0f)
- repository.setClockPosition(100, 100)
- assertThat(value()).isEqualTo(100f)
- repository.setClockPosition(200, 100)
- assertThat(value()).isEqualTo(200f)
- repository.setClockPosition(200, 200)
- assertThat(value()).isEqualTo(200f)
- repository.setClockPosition(300, 100)
- assertThat(value()).isEqualTo(300f)
- }
-
- @Test
- fun indicationAreaTranslationY() =
- testScope.runTest {
- val value =
- collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
-
- // Negative 0 - apparently there's a difference in floating point arithmetic - FML
- assertThat(value()).isEqualTo(-0f)
- val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
- assertThat(value()).isEqualTo(expected1)
- val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
- assertThat(value()).isEqualTo(expected2)
- val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
- assertThat(value()).isEqualTo(expected3)
- val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
- assertThat(value()).isEqualTo(expected4)
- }
-
- @Test
fun isClickable_trueWhenAlphaAtThreshold() =
testScope.runTest {
repository.setKeyguardShowing(true)
@@ -757,11 +665,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
)
}
- private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
- repository.setDozeAmount(dozeAmount)
- return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
- }
-
private suspend fun setUpQuickAffordanceModel(
position: KeyguardQuickAffordancePosition,
testConfig: TestConfig,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
new file mode 100644
index 000000000000..dff0f2909126
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.doze.util.BurnInHelperWrapper
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
+
+ @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
+
+ private lateinit var underTest: KeyguardIndicationAreaViewModel
+ private lateinit var repository: FakeKeyguardRepository
+
+ private val startButtonFlow =
+ MutableStateFlow<KeyguardQuickAffordanceViewModel>(
+ KeyguardQuickAffordanceViewModel(
+ slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId()
+ )
+ )
+ private val endButtonFlow =
+ MutableStateFlow<KeyguardQuickAffordanceViewModel>(
+ KeyguardQuickAffordanceViewModel(
+ slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId()
+ )
+ )
+ private val alphaFlow = MutableStateFlow<Float>(1f)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
+ .thenReturn(RETURNED_BURN_IN_OFFSET)
+
+ val withDeps = KeyguardInteractorFactory.create()
+ val keyguardInteractor = withDeps.keyguardInteractor
+ repository = withDeps.repository
+
+ val bottomAreaViewModel: KeyguardBottomAreaViewModel = mock()
+ whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow)
+ whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow)
+ whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow)
+ underTest =
+ KeyguardIndicationAreaViewModel(
+ keyguardInteractor = keyguardInteractor,
+ bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
+ keyguardBottomAreaViewModel = bottomAreaViewModel,
+ burnInHelperWrapper = burnInHelperWrapper,
+ )
+ }
+
+ @Test
+ fun alpha() = runTest {
+ val value = collectLastValue(underTest.alpha)
+
+ assertThat(value()).isEqualTo(1f)
+ alphaFlow.value = 0.1f
+ assertThat(value()).isEqualTo(0.1f)
+ alphaFlow.value = 0.5f
+ assertThat(value()).isEqualTo(0.5f)
+ alphaFlow.value = 0.2f
+ assertThat(value()).isEqualTo(0.2f)
+ alphaFlow.value = 0f
+ assertThat(value()).isEqualTo(0f)
+ }
+
+ @Test
+ fun isIndicationAreaPadded() = runTest {
+ repository.setKeyguardShowing(true)
+ val value = collectLastValue(underTest.isIndicationAreaPadded)
+
+ assertThat(value()).isFalse()
+ startButtonFlow.value = startButtonFlow.value.copy(isVisible = true)
+ assertThat(value()).isTrue()
+ endButtonFlow.value = endButtonFlow.value.copy(isVisible = true)
+ assertThat(value()).isTrue()
+ startButtonFlow.value = startButtonFlow.value.copy(isVisible = false)
+ assertThat(value()).isTrue()
+ endButtonFlow.value = endButtonFlow.value.copy(isVisible = false)
+ assertThat(value()).isFalse()
+ }
+
+ @Test
+ fun indicationAreaTranslationX() = runTest {
+ val value = collectLastValue(underTest.indicationAreaTranslationX)
+
+ assertThat(value()).isEqualTo(0f)
+ repository.setClockPosition(100, 100)
+ assertThat(value()).isEqualTo(100f)
+ repository.setClockPosition(200, 100)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(200, 200)
+ assertThat(value()).isEqualTo(200f)
+ repository.setClockPosition(300, 100)
+ assertThat(value()).isEqualTo(300f)
+ }
+
+ @Test
+ fun indicationAreaTranslationY() = runTest {
+ val value = collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
+
+ // Negative 0 - apparently there's a difference in floating point arithmetic - FML
+ assertThat(value()).isEqualTo(-0f)
+ val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
+ assertThat(value()).isEqualTo(expected1)
+ val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
+ assertThat(value()).isEqualTo(expected2)
+ val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
+ assertThat(value()).isEqualTo(expected3)
+ val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
+ assertThat(value()).isEqualTo(expected4)
+ }
+
+ private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
+ repository.setDozeAmount(dozeAmount)
+ return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
+ }
+
+ companion object {
+ private const val DEFAULT_BURN_IN_OFFSET = 5
+ private const val RETURNED_BURN_IN_OFFSET = 3
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 8ba3f0f57eed..f0ea0077596a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -109,7 +109,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
testScope.runTest {
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
@@ -119,7 +119,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
runCurrent()
@@ -132,7 +132,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
runCurrent()
@@ -145,7 +145,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
runCurrent()
@@ -158,7 +158,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
index 97b18e214550..d6ceea11b801 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt
@@ -234,4 +234,17 @@ class SeekBarObserverTest : SysuiTestCase() {
assertThat(seekBarView.progress).isEqualTo(4000)
verify(mockSeekbarAnimator).start()
}
+
+ @Test
+ fun seekbarActive_animationsDisabled() {
+ // WHEN playing, but animations have been disabled
+ observer.animationEnabled = false
+ val isPlaying = true
+ val isScrubbing = false
+ val data = SeekBarViewModel.Progress(true, true, isPlaying, isScrubbing, 3000, 120000)
+ observer.onChanged(data)
+
+ // THEN progress drawable does not animate
+ verify(mockSquigglyProgress).animate = false
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 3bcefcf6ffff..56698e0ec41c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -41,7 +41,6 @@ import android.testing.TestableLooper.RunWithLooper
import androidx.media.utils.MediaConstants
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
-import com.android.internal.statusbar.IStatusBarService
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.InstanceIdSequenceFake
import com.android.systemui.R
@@ -133,7 +132,6 @@ class MediaDataManagerTest : SysuiTestCase() {
@Mock lateinit var activityStarter: ActivityStarter
@Mock lateinit var smartspaceManager: SmartspaceManager
@Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
- @Mock lateinit var statusBarService: IStatusBarService
lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
@Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
@Mock private lateinit var mediaRecommendationItem: SmartspaceAction
@@ -197,7 +195,6 @@ class MediaDataManagerTest : SysuiTestCase() {
logger = logger,
smartspaceManager = smartspaceManager,
keyguardUpdateMonitor = keyguardUpdateMonitor,
- statusBarService = statusBarService,
)
verify(tunerService)
.addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
@@ -522,143 +519,12 @@ class MediaDataManagerTest : SysuiTestCase() {
}
@Test
- fun testOnNotificationAdded_emptyTitle_isRequired_notLoaded() {
- // When the manager has a notification with an empty title, and the app is required
- // to include a non-empty title
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(true)
- whenever(controller.metadata)
- .thenReturn(
- metadataBuilder
- .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_EMPTY_TITLE)
- .build()
- )
- mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-
- // Then the media control is not added and we report a notification error
- assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
- assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(statusBarService)
- .onNotificationError(
- eq(PACKAGE_NAME),
- eq(mediaNotification.tag),
- eq(mediaNotification.id),
- eq(mediaNotification.uid),
- eq(mediaNotification.initialPid),
- eq(MEDIA_TITLE_ERROR_MESSAGE),
- eq(mediaNotification.user.identifier)
- )
- verify(listener, never())
- .onMediaDataLoaded(
- eq(KEY),
- eq(null),
- capture(mediaDataCaptor),
- eq(true),
- eq(0),
- eq(false)
- )
- verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
- verify(logger, never()).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), any())
- }
-
- @Test
- fun testOnNotificationAdded_blankTitle_isRequired_notLoaded() {
- // When the manager has a notification with a blank title, and the app is required
- // to include a non-empty title
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(true)
- whenever(controller.metadata)
- .thenReturn(
- metadataBuilder
- .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
- .build()
- )
- mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-
- // Then the media control is not added and we report a notification error
- assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
- assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(statusBarService)
- .onNotificationError(
- eq(PACKAGE_NAME),
- eq(mediaNotification.tag),
- eq(mediaNotification.id),
- eq(mediaNotification.uid),
- eq(mediaNotification.initialPid),
- eq(MEDIA_TITLE_ERROR_MESSAGE),
- eq(mediaNotification.user.identifier)
- )
- verify(listener, never())
- .onMediaDataLoaded(
- eq(KEY),
- eq(null),
- capture(mediaDataCaptor),
- eq(true),
- eq(0),
- eq(false)
- )
- verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
- verify(logger, never()).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), any())
- }
-
- @Test
- fun testOnNotificationUpdated_invalidTitle_isRequired_logMediaRemoved() {
- // When the app is required to provide a non-blank title, and updates a previously valid
- // title to an empty one
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(true)
- addNotificationAndLoad()
- val data = mediaDataCaptor.value
-
- verify(listener)
- .onMediaDataLoaded(
- eq(KEY),
- eq(null),
- capture(mediaDataCaptor),
- eq(true),
- eq(0),
- eq(false)
- )
-
- reset(listener)
- whenever(controller.metadata)
- .thenReturn(
- metadataBuilder
- .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
- .build()
- )
- mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-
- // Then the media control is removed
- assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
- assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
- verify(statusBarService)
- .onNotificationError(
- eq(PACKAGE_NAME),
- eq(mediaNotification.tag),
- eq(mediaNotification.id),
- eq(mediaNotification.uid),
- eq(mediaNotification.initialPid),
- eq(MEDIA_TITLE_ERROR_MESSAGE),
- eq(mediaNotification.user.identifier)
- )
- verify(listener, never())
- .onMediaDataLoaded(
- eq(KEY),
- eq(null),
- capture(mediaDataCaptor),
- eq(true),
- eq(0),
- eq(false)
- )
- verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
- }
-
- @Test
- fun testOnNotificationAdded_emptyTitle_notRequired_hasPlaceholder() {
+ fun testOnNotificationAdded_emptyTitle_hasPlaceholder() {
// When the manager has a notification with an empty title, and the app is not
// required to include a non-empty title
val mockPackageManager = mock(PackageManager::class.java)
context.setMockPackageManager(mockPackageManager)
whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(false)
whenever(controller.metadata)
.thenReturn(
metadataBuilder
@@ -684,13 +550,12 @@ class MediaDataManagerTest : SysuiTestCase() {
}
@Test
- fun testOnNotificationAdded_blankTitle_notRequired_hasPlaceholder() {
+ fun testOnNotificationAdded_blankTitle_hasPlaceholder() {
// GIVEN that the manager has a notification with a blank title, and the app is not
// required to include a non-empty title
val mockPackageManager = mock(PackageManager::class.java)
context.setMockPackageManager(mockPackageManager)
whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(false)
whenever(controller.metadata)
.thenReturn(
metadataBuilder
@@ -722,7 +587,6 @@ class MediaDataManagerTest : SysuiTestCase() {
val mockPackageManager = mock(PackageManager::class.java)
context.setMockPackageManager(mockPackageManager)
whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
- whenever(mediaFlags.isMediaTitleRequired(any(), any())).thenReturn(true)
whenever(controller.metadata)
.thenReturn(
metadataBuilder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index f030a03be80f..7b673bc2b31e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -25,6 +25,7 @@ import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
+import android.database.ContentObserver
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
@@ -40,6 +41,7 @@ import android.media.MediaMetadata
import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.os.Bundle
+import android.provider.Settings
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -73,6 +75,7 @@ import com.android.systemui.media.controls.models.player.MediaButton
import com.android.systemui.media.controls.models.player.MediaData
import com.android.systemui.media.controls.models.player.MediaDeviceData
import com.android.systemui.media.controls.models.player.MediaViewHolder
+import com.android.systemui.media.controls.models.player.SeekBarObserver
import com.android.systemui.media.controls.models.player.SeekBarViewModel
import com.android.systemui.media.controls.models.recommendation.KEY_SMARTSPACE_APP_NAME
import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
@@ -97,6 +100,7 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import dagger.Lazy
@@ -109,6 +113,7 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
@@ -233,6 +238,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true)
this.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, false)
}
+ @Mock private lateinit var globalSettings: GlobalSettings
+ @Captor private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
@JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -273,7 +280,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
activityIntentHelper,
lockscreenUserManager,
broadcastDialogController,
- fakeFeatureFlag
+ fakeFeatureFlag,
+ globalSettings,
) {
override fun loadAnimator(
animId: Int,
@@ -284,6 +292,12 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
}
+ verify(globalSettings)
+ .registerContentObserver(
+ eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)),
+ settingsObserverCaptor.capture()
+ )
+
initGutsViewHolderMocks()
initMediaViewHolderMocks()
@@ -955,6 +969,30 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
@Test
+ fun animationSettingChange_updateSeekbar() {
+ // When animations are enabled
+ globalSettings.putFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 1f)
+ val progress = 0.5
+ val state = mediaData.copy(resumption = true, resumeProgress = progress)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state, PACKAGE)
+
+ val captor = argumentCaptor<SeekBarObserver>()
+ verify(seekBarData).observeForever(captor.capture())
+ val seekBarObserver = captor.value!!
+
+ // Then the seekbar is set to animate
+ assertThat(seekBarObserver.animationEnabled).isTrue()
+
+ // When the setting changes,
+ globalSettings.putFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 0f)
+ settingsObserverCaptor.value!!.onChange(false)
+
+ // Then the seekbar is set to not animate
+ assertThat(seekBarObserver.animationEnabled).isFalse()
+ }
+
+ @Test
fun bindNotificationActions() {
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index c89897c0233c..6d8c9b106881 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -247,6 +247,20 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
}
@Test
+ public void onBindViewHolder_bindConnectedRemoteDevice_verifyContentDescriptionNotNull() {
+ when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
+ ImmutableList.of(mMediaDevice2));
+ when(mMediaOutputController.isCurrentConnectedDeviceRemote()).thenReturn(true);
+ mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ .onCreateViewHolder(new LinearLayout(mContext), 0);
+ mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.mSeekBar.getContentDescription()).isNotNull();
+ assertThat(mViewHolder.mSeekBar.getAccessibilityDelegate()).isNotNull();
+ assertThat(mViewHolder.mContainerLayout.isFocusable()).isFalse();
+ }
+
+ @Test
public void onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
ImmutableList.of());
@@ -334,6 +348,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+ assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
index bd042c23856d..ffbf62aad2b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
@@ -26,6 +26,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.view.ViewUtil
@@ -48,6 +49,7 @@ class FakeMediaTttChipControllerReceiver(
wakeLockBuilder: WakeLock.Builder,
systemClock: SystemClock,
rippleController: MediaTttReceiverRippleController,
+ temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
) :
MediaTttChipControllerReceiver(
commandQueue,
@@ -66,6 +68,7 @@ class FakeMediaTttChipControllerReceiver(
wakeLockBuilder,
systemClock,
rippleController,
+ temporaryViewUiEventLogger,
) {
override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
// Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 19dd2f035c62..2b66e7b3cd80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -31,6 +31,7 @@ import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.widget.ImageView
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -38,6 +39,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -90,6 +92,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
private lateinit var fakeAppIconDrawable: Drawable
private lateinit var uiEventLoggerFake: UiEventLoggerFake
private lateinit var receiverUiEventLogger: MediaTttReceiverUiEventLogger
+ private lateinit var temporaryViewUiEventLogger: TemporaryViewUiEventLogger
private lateinit var fakeClock: FakeSystemClock
private lateinit var fakeExecutor: FakeExecutor
private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
@@ -114,6 +117,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
uiEventLoggerFake = UiEventLoggerFake()
receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+ temporaryViewUiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
fakeWakeLock = WakeLockFake()
fakeWakeLockBuilder = WakeLockFake.Builder(context)
@@ -136,6 +140,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
fakeWakeLockBuilder,
fakeClock,
rippleController,
+ temporaryViewUiEventLogger,
)
controllerReceiver.start()
@@ -166,6 +171,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
fakeWakeLockBuilder,
fakeClock,
rippleController,
+ temporaryViewUiEventLogger,
)
controllerReceiver.start()
@@ -186,6 +192,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
)
+ assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
@@ -201,6 +208,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
)
+ assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
@@ -216,6 +224,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
)
+ assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
@@ -231,6 +240,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED.id
)
+ assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
@@ -276,6 +286,25 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
}
@Test
+ fun commandQueueCallback_closeThenSucceeded_sameViewInstanceId() {
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+ routeInfo,
+ null,
+ null
+ )
+
+ commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ routeInfo,
+ null,
+ null
+ )
+
+ assertThat(uiEventLoggerFake[0].instanceId).isEqualTo(uiEventLoggerFake[1].instanceId)
+ }
+
+ @Test
fun commandQueueCallback_closeThenFailed_chipShownThenHidden() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
@@ -349,6 +378,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
appIconDrawableOverride = null,
appNameOverride = null,
id = "id",
+ instanceId = InstanceId.fakeInstanceId(0),
)
)
@@ -371,6 +401,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
drawableOverride,
appNameOverride = null,
id = "id",
+ instanceId = InstanceId.fakeInstanceId(0),
)
)
@@ -388,6 +419,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
appIconDrawableOverride = null,
appNameOverride,
id = "id",
+ instanceId = InstanceId.fakeInstanceId(0),
)
)
@@ -442,7 +474,13 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
.addFeature("feature")
.setClientPackageName(packageName)
.build()
- return ChipReceiverInfo(routeInfo, null, null, id = "id")
+ return ChipReceiverInfo(
+ routeInfo,
+ null,
+ null,
+ id = "id",
+ instanceId = InstanceId.fakeInstanceId(0),
+ )
}
private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
index ee10ddc521f1..f55771362cb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
@@ -1,6 +1,7 @@
package com.android.systemui.media.taptotransfer.receiver
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -21,10 +22,12 @@ class MediaTttReceiverUiEventLoggerTest : SysuiTestCase() {
@Test
fun logReceiverStateChange_eventAssociatedWithStateIsLogged() {
val state = ChipStateReceiver.CLOSE_TO_SENDER
+ val instanceId = InstanceId.fakeInstanceId(0)
- logger.logReceiverStateChange(state)
+ logger.logReceiverStateChange(state, instanceId)
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+ assertThat(uiEventLoggerFake.logs[0].instanceId).isEqualTo(instanceId)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index 349fac0bf6ea..ea25f712f06a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -46,6 +46,7 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.temporarydisplay.chipbar.ChipbarAnimator
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger
@@ -108,6 +109,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
private lateinit var fakeExecutor: FakeExecutor
private lateinit var uiEventLoggerFake: UiEventLoggerFake
private lateinit var uiEventLogger: MediaTttSenderUiEventLogger
+ private lateinit var tempViewUiEventLogger: TemporaryViewUiEventLogger
private val defaultTimeout = context.resources.getInteger(R.integer.heads_up_notification_decay)
@Before
@@ -137,6 +139,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
uiEventLoggerFake = UiEventLoggerFake()
uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
+ tempViewUiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
chipbarCoordinator =
ChipbarCoordinator(
@@ -156,6 +159,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
vibratorHelper,
fakeWakeLockBuilder,
fakeClock,
+ tempViewUiEventLogger,
)
chipbarCoordinator.start()
@@ -352,8 +356,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
.isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText())
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
- // Event index 1 since initially displaying the triggered chip would also log an event.
- assertThat(uiEventLoggerFake.eventId(1))
+ // Event index 2 since initially displaying the triggered chip would also log two events.
+ assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
verify(vibratorHelper, never())
.vibrate(
@@ -366,6 +370,24 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
}
@Test
+ fun commandQueueCallback_transferToReceiverSucceeded_sameViewInstanceId() {
+ displayReceiverTriggered()
+ reset(vibratorHelper)
+ commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ routeInfo,
+ null
+ )
+
+ // Event index 2 since initially displaying the triggered chip would also log two events.
+ assertThat(uiEventLoggerFake.eventId(2))
+ .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
+ verify(vibratorHelper, never()).vibrate(any<VibrationEffect>())
+ assertThat(uiEventLoggerFake.logs[0].instanceId)
+ .isEqualTo(uiEventLoggerFake.logs[2].instanceId)
+ }
+
+ @Test
fun transferToReceiverSucceeded_nullUndoCallback_noUndo() {
displayReceiverTriggered()
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
@@ -410,9 +432,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
getChipbarView().getUndoButton().performClick()
- // Event index 2 since initially displaying the triggered and succeeded chip would also log
+ // Event index 3 since initially displaying the triggered and succeeded chip would also log
// events.
- assertThat(uiEventLoggerFake.eventId(2))
+ assertThat(uiEventLoggerFake.eventId(3))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id)
assertThat(undoCallbackCalled).isTrue()
assertThat(getChipbarView().getChipText())
@@ -436,8 +458,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
.isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText())
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
- // Event index 1 since initially displaying the triggered chip would also log an event.
- assertThat(uiEventLoggerFake.eventId(1))
+ // Event index 2 since initially displaying the triggered chip would also log two events.
+ assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id)
verify(vibratorHelper, never())
.vibrate(
@@ -494,9 +516,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
getChipbarView().getUndoButton().performClick()
- // Event index 2 since initially displaying the triggered and succeeded chip would also log
+ // Event index 3 since initially displaying the triggered and succeeded chip would also log
// events.
- assertThat(uiEventLoggerFake.eventId(2))
+ assertThat(uiEventLoggerFake.eventId(3))
.isEqualTo(
MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id
)
@@ -523,8 +545,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
- // Event index 1 since initially displaying the triggered chip would also log an event.
- assertThat(uiEventLoggerFake.eventId(1))
+ // Event index 2 since initially displaying the triggered chip would also log two events.
+ assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id)
verify(vibratorHelper)
.vibrate(
@@ -559,7 +581,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
// Event index 1 since initially displaying the triggered chip would also log an event.
- assertThat(uiEventLoggerFake.eventId(1))
+ assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id)
verify(vibratorHelper)
.vibrate(
@@ -1082,6 +1104,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun newState_viewListenerRegistered() {
val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+ whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
underTest =
MediaTttSenderCoordinator(
mockChipbarCoordinator,
@@ -1109,6 +1132,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun onInfoPermanentlyRemoved_viewListenerUnregistered() {
val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+ whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
underTest =
MediaTttSenderCoordinator(
mockChipbarCoordinator,
@@ -1142,6 +1166,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun onInfoPermanentlyRemoved_wrongId_viewListenerNotUnregistered() {
val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+ whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
underTest =
MediaTttSenderCoordinator(
mockChipbarCoordinator,
@@ -1174,6 +1199,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun farFromReceiverState_viewListenerUnregistered() {
val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+ whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
underTest =
MediaTttSenderCoordinator(
mockChipbarCoordinator,
@@ -1210,6 +1236,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun statesWithDifferentIds_onInfoPermanentlyRemovedForOneId_viewListenerNotUnregistered() {
val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+ whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
underTest =
MediaTttSenderCoordinator(
mockChipbarCoordinator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
index 2287da572795..ee3704c1e9e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.taptotransfer.sender
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.LogBuffer
@@ -91,8 +92,16 @@ class MediaTttSenderLoggerTest : SysuiTestCase() {
fun logStateMap_bufferHasInfo() {
val map =
mapOf(
- "123" to ChipStateSender.ALMOST_CLOSE_TO_START_CAST,
- "456" to ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+ "123" to
+ Pair(
+ InstanceId.fakeInstanceId(100),
+ ChipStateSender.ALMOST_CLOSE_TO_START_CAST
+ ),
+ "456" to
+ Pair(
+ InstanceId.fakeInstanceId(200),
+ ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED
+ ),
)
logger.logStateMap(map)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
index 263637a6b6e5..bf26a2f53b4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
@@ -1,6 +1,7 @@
package com.android.systemui.media.taptotransfer.sender
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -21,26 +22,32 @@ class MediaTttSenderUiEventLoggerTest : SysuiTestCase() {
@Test
fun logSenderStateChange_eventAssociatedWithStateIsLogged() {
val state = ChipStateSender.ALMOST_CLOSE_TO_END_CAST
- logger.logSenderStateChange(state)
+ logger.logSenderStateChange(state, instanceId)
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+ assertThat(uiEventLoggerFake.get(0).instanceId).isEqualTo(instanceId)
}
@Test
fun logUndoClicked_undoEventLogged() {
val undoEvent = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
- logger.logUndoClicked(undoEvent)
+ logger.logUndoClicked(undoEvent, instanceId)
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(undoEvent.id)
+ assertThat(uiEventLoggerFake.get(0).instanceId).isEqualTo(instanceId)
}
@Test
fun logUndoClicked_notUndoEvent_eventNotLogged() {
- logger.logUndoClicked(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED)
+ val state = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED
+
+ logger.logUndoClicked(state, instanceId)
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
}
}
+
+private val instanceId = InstanceId.fakeInstanceId(0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index 9b8605dccd09..8d306cceeaa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -52,6 +52,7 @@ import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -112,6 +113,9 @@ public class NavBarHelperTest extends SysuiTestCase {
EdgeBackGestureHandler mEdgeBackGestureHandler;
@Mock
EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+ @Mock
+ NotificationShadeWindowController mNotificationShadeWindowController;
+
private AccessibilityManager.AccessibilityServicesStateChangeListener
mAccessibilityServicesStateChangeListener;
@@ -136,7 +140,7 @@ public class NavBarHelperTest extends SysuiTestCase {
mSystemActions, mOverviewProxyService, mAssistManagerLazy,
() -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class),
mNavigationModeController, mEdgeBackGestureHandlerFactory, mWm, mUserTracker,
- mDisplayTracker, mDumpManager, mCommandQueue);
+ mDisplayTracker, mNotificationShadeWindowController, mDumpManager, mCommandQueue);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index f062ec732b21..25d494cee5e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -99,6 +99,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarController;
@@ -209,6 +210,8 @@ public class NavigationBarTest extends SysuiTestCase {
private EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
@Mock
private EdgeBackGestureHandler mEdgeBackGestureHandler;
+ @Mock
+ private NotificationShadeWindowController mNotificationShadeWindowController;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
private TaskStackChangeListeners mTaskStackChangeListeners =
@@ -256,7 +259,8 @@ public class NavigationBarTest extends SysuiTestCase {
() -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces),
mKeyguardStateController, mock(NavigationModeController.class),
mEdgeBackGestureHandlerFactory, mock(IWindowManager.class),
- mock(UserTracker.class), mock(DisplayTracker.class), mock(DumpManager.class),
+ mock(UserTracker.class), mock(DisplayTracker.class),
+ mNotificationShadeWindowController, mock(DumpManager.class),
mock(CommandQueue.class)));
mNavigationBar = createNavBar(mContext);
mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
@@ -339,7 +343,6 @@ public class NavigationBarTest extends SysuiTestCase {
NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
- doReturn(mockShadeWindowView).when(mCentralSurfaces).getNotificationShadeWindowView();
doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
doNothing().when(defaultNavBar).checkNavBarModes();
doNothing().when(externalNavBar).checkNavBarModes();
@@ -375,7 +378,7 @@ public class NavigationBarTest extends SysuiTestCase {
@Test
public void testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange() {
NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
- doReturn(mockShadeWindowView).when(mCentralSurfaces).getNotificationShadeWindowView();
+ doReturn(mockShadeWindowView).when(mNotificationShadeWindowController).getWindowRootView();
doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
doNothing().when(mNavigationBar).checkNavBarModes();
mNavigationBar.init();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 079ef372cae6..204077bd927b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -36,7 +36,6 @@ import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.content.pm.UserInfo
import android.graphics.drawable.Icon
@@ -62,6 +61,7 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.settings.SecureSettings
@@ -115,7 +115,11 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(context.getString(R.string.note_task_button_label))
.thenReturn(NOTE_TASK_SHORT_LABEL)
+ whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any()))
+ .thenReturn(NOTE_TASK_LONG_LABEL)
whenever(context.packageManager).thenReturn(packageManager)
+ whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
+ whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
whenever(userManager.isUserUnlocked).thenReturn(true)
whenever(userManager.isUserUnlocked(any<Int>())).thenReturn(true)
@@ -706,19 +710,20 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
verify(shortcutManager, never()).disableShortcuts(any())
verify(shortcutManager).enableShortcuts(listOf(SHORTCUT_ID))
- val actualShortcuts = argumentCaptor<List<ShortcutInfo>>()
- verify(shortcutManager).updateShortcuts(actualShortcuts.capture())
- val actualShortcut = actualShortcuts.value.first()
- assertThat(actualShortcut.id).isEqualTo(SHORTCUT_ID)
- assertThat(actualShortcut.intent).run {
- hasComponentClass(LaunchNoteTaskActivity::class.java)
- hasAction(ACTION_CREATE_NOTE)
+ val shortcutInfo = withArgCaptor { verify(shortcutManager).updateShortcuts(capture()) }
+ with(shortcutInfo.first()) {
+ assertThat(id).isEqualTo(SHORTCUT_ID)
+ assertThat(intent).run {
+ hasComponentClass(LaunchNoteTaskActivity::class.java)
+ hasAction(ACTION_CREATE_NOTE)
+ }
+ assertThat(shortLabel).isEqualTo(NOTE_TASK_SHORT_LABEL)
+ assertThat(longLabel).isEqualTo(NOTE_TASK_LONG_LABEL)
+ assertThat(isLongLived).isEqualTo(true)
+ assertThat(icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
+ assertThat(extras?.getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE))
+ .isEqualTo(NOTE_TASK_PACKAGE_NAME)
}
- assertThat(actualShortcut.shortLabel).isEqualTo(NOTE_TASK_SHORT_LABEL)
- assertThat(actualShortcut.isLongLived).isEqualTo(true)
- assertThat(actualShortcut.icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
- assertThat(actualShortcut.extras?.getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE))
- .isEqualTo(NOTE_TASK_PACKAGE_NAME)
}
@Test
@@ -893,7 +898,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
// endregion
private companion object {
- const val NOTE_TASK_SHORT_LABEL = "Notetaking"
+ const val NOTE_TASK_SHORT_LABEL = "Note-taking"
+ const val NOTE_TASK_LONG_LABEL = "Note-taking, App"
const val NOTE_TASK_ACTIVITY_NAME = "NoteTaskActivity"
const val NOTE_TASK_PACKAGE_NAME = "com.android.note.app"
const val NOTE_TASK_UID = 123456
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 105387d49bd4..05a16994e021 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -70,7 +70,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
runCurrent()
@@ -83,7 +83,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index 3def6ba1fc58..f2812b5857b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -16,9 +16,11 @@
package com.android.systemui.screenrecord;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
@@ -32,6 +34,7 @@ import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
@@ -41,7 +44,9 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.MediaProjectionCaptureTarget;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
import org.junit.Test;
@@ -77,20 +82,38 @@ public class RecordingServiceTest extends SysuiTestCase {
private UserContextProvider mUserContextTracker;
@Captor
private ArgumentCaptor<Runnable> mRunnableCaptor;
- private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil() {
- public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
- boolean requiresShadeOpen) {
- action.onDismiss();
- }
- };
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private SysuiStatusBarStateController mStatusBarStateController;
+ @Mock
+ private ActivityStarter mActivityStarter;
+
+ private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+
+ private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil(
+ mKeyguardStateController, mStatusBarStateController, mActivityStarter);
private RecordingService mRecordingService;
+ private class RecordingServiceTestable extends RecordingService {
+ RecordingServiceTestable(
+ RecordingController controller, Executor executor,
+ Handler handler, UiEventLogger uiEventLogger,
+ NotificationManager notificationManager,
+ UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil) {
+ super(controller, executor, handler,
+ uiEventLogger, notificationManager, userContextTracker, keyguardDismissUtil);
+ attachBaseContext(mContext);
+ }
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mHandler,
- mUiEventLogger, mNotificationManager, mUserContextTracker, mKeyguardDismissUtil));
+ mRecordingService = Mockito.spy(new RecordingServiceTestable(mController, mExecutor,
+ mHandler, mUiEventLogger, mNotificationManager,
+ mUserContextTracker, mKeyguardDismissUtil));
// Return actual context info
doReturn(mContext).when(mRecordingService).getApplicationContext();
@@ -160,8 +183,7 @@ public class RecordingServiceTest extends SysuiTestCase {
Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false, null);
mRecordingService.onStartCommand(startIntent, 0, 0);
- // Then the state is set to not recording
- verify(mController).updateState(false);
+ assertUpdateState(false);
}
@Test
@@ -179,7 +201,7 @@ public class RecordingServiceTest extends SysuiTestCase {
mRecordingService.onStopped();
- verify(mController).updateState(false);
+ assertUpdateState(false);
}
@Test
@@ -224,8 +246,21 @@ public class RecordingServiceTest extends SysuiTestCase {
verify(mExecutor).execute(mRunnableCaptor.capture());
mRunnableCaptor.getValue().run();
- // Then the state is set to not recording and we cancel the notification
- verify(mController).updateState(false);
+ assertUpdateState(false);
verify(mNotificationManager).cancelAsUser(any(), anyInt(), any());
}
+
+ private void assertUpdateState(boolean state) {
+ // Then the state is set to not recording, and we cancel the notification
+ // non SYSTEM user doesn't have the reference to the correct controller,
+ // so a broadcast is sent in case of non SYSTEM user.
+ if (UserHandle.USER_SYSTEM == mContext.getUserId()) {
+ verify(mController).updateState(state);
+ } else {
+ ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mRecordingService).sendBroadcast(argumentCaptor.capture(), eq(PERMISSION_SELF));
+ assertEquals(RecordingController.INTENT_UPDATE_STATE,
+ argumentCaptor.getValue().getAction());
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
index 5b094c93ea9d..07feedf1d654 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
@@ -104,6 +104,26 @@ class ScreenRecordPermissionDialogTest : SysuiTestCase() {
assertThat(visibility).isEqualTo(View.VISIBLE)
}
+ @Test
+ fun showDialog_dialogIsShowing() {
+ dialog.show()
+
+ assertThat(dialog.isShowing).isTrue()
+ }
+
+ @Test
+ fun showDialog_cancelClicked_dialogIsDismissed() {
+ dialog.show()
+
+ clickOnCancel()
+
+ assertThat(dialog.isShowing).isFalse()
+ }
+
+ private fun clickOnCancel() {
+ dialog.requireViewById<View>(android.R.id.button2).performClick()
+ }
+
private fun onSpinnerItemSelected(position: Int) {
val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
spinner.onItemSelectedListener.onItemSelected(spinner, mock(), position, /* id= */ 0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index fe89a143e880..ee382d30c1dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -89,12 +89,13 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
+import com.android.systemui.keyguard.KeyguardViewConfigurator;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
@@ -253,6 +254,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock protected UserManager mUserManager;
@Mock protected UiEventLogger mUiEventLogger;
@Mock protected LockIconViewController mLockIconViewController;
+ @Mock protected KeyguardViewConfigurator mKeyguardViewConfigurator;
@Mock protected KeyguardMediaController mKeyguardMediaController;
@Mock protected NavigationModeController mNavigationModeController;
@Mock protected NavigationBarController mNavigationBarController;
@@ -313,6 +315,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
protected final int mMaxUdfpsBurnInOffsetY = 5;
protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
+ protected FakeKeyguardRepository mFakeKeyguardRepository;
protected KeyguardInteractor mKeyguardInteractor;
protected NotificationPanelViewController.TouchHandler mTouchHandler;
protected ConfigurationController mConfigurationController;
@@ -340,10 +343,12 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
mMainDispatcher = getMainDispatcher();
- mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor(
- new FakeKeyguardRepository());
- mKeyguardInteractor = new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue,
- mFeatureFlags, new FakeKeyguardBouncerRepository());
+ KeyguardInteractorFactory.WithDependencies keyguardInteractorDeps =
+ KeyguardInteractorFactory.create();
+ mFakeKeyguardRepository = keyguardInteractorDeps.getRepository();
+ mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor(mFakeKeyguardRepository);
+ mKeyguardInteractor = keyguardInteractorDeps.getKeyguardInteractor();
+
SystemClock systemClock = new FakeSystemClock();
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
mInteractionJankMonitor, mShadeExpansionStateManager);
@@ -611,6 +616,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mKeyuardLongPressViewModel,
mKeyguardInteractor,
mActivityStarter,
+ mKeyguardViewConfigurator,
mKeyguardFaceAuthInteractor);
mNotificationPanelViewController.initDependencies(
mCentralSurfaces,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index a5a9de54c558..b1f8475f7d74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -58,6 +58,9 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.FaceAuthApiRequestReason;
import com.android.systemui.DejankUtils;
import com.android.systemui.R;
+import com.android.systemui.keyguard.shared.model.WakeSleepReason;
+import com.android.systemui.keyguard.shared.model.WakefulnessModel;
+import com.android.systemui.keyguard.shared.model.WakefulnessState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
@@ -1162,4 +1165,43 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
when(mUnlockedScreenOffAnimationController.isAnimationPlaying()).thenReturn(true);
assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
}
+
+ @Test
+ public void getFalsingThreshold_deviceNotInteractive_isQsThreshold() {
+ mFakeKeyguardRepository.setWakefulnessModel(
+ new WakefulnessModel(
+ WakefulnessState.ASLEEP,
+ /* lastWakeReason= */ WakeSleepReason.TAP,
+ /* lastSleepReason= */ WakeSleepReason.POWER_BUTTON)
+ );
+ when(mQsController.getFalsingThreshold()).thenReturn(14);
+
+ assertThat(mNotificationPanelViewController.getFalsingThreshold()).isEqualTo(14);
+ }
+
+ @Test
+ public void getFalsingThreshold_lastWakeNotDueToTouch_isQsThreshold() {
+ mFakeKeyguardRepository.setWakefulnessModel(
+ new WakefulnessModel(
+ WakefulnessState.AWAKE,
+ /* lastWakeReason= */ WakeSleepReason.POWER_BUTTON,
+ /* lastSleepReason= */ WakeSleepReason.POWER_BUTTON)
+ );
+ when(mQsController.getFalsingThreshold()).thenReturn(14);
+
+ assertThat(mNotificationPanelViewController.getFalsingThreshold()).isEqualTo(14);
+ }
+
+ @Test
+ public void getFalsingThreshold_lastWakeDueToTouch_greaterThanQsThreshold() {
+ mFakeKeyguardRepository.setWakefulnessModel(
+ new WakefulnessModel(
+ WakefulnessState.AWAKE,
+ /* lastWakeReason= */ WakeSleepReason.TAP,
+ /* lastSleepReason= */ WakeSleepReason.POWER_BUTTON)
+ );
+ when(mQsController.getFalsingThreshold()).thenReturn(14);
+
+ assertThat(mNotificationPanelViewController.getFalsingThreshold()).isGreaterThan(14);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 526dc8d150fe..cde6ac08d5fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -126,7 +126,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
}
};
mNotificationShadeWindowController.setScrimsVisibilityListener((visibility) -> {});
- mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
+ mNotificationShadeWindowController.setWindowRootView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
verify(mWindowManager).addView(eq(mNotificationShadeWindowView), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index 34d09a912c87..ff047aa2faf2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -580,6 +580,30 @@ public class QuickSettingsControllerTest extends SysuiTestCase {
verify(mQs).setQsVisible(true);
}
+ @Test
+ public void calculateBottomCornerRadius_scrimScaleMax() {
+ when(mScrimController.getBackScaling()).thenReturn(1.0f);
+ assertThat(mQsController.calculateBottomCornerRadius(0.0f)).isEqualTo(0);
+ }
+
+ @Test
+ public void calculateBottomCornerRadius_scrimScaleMin() {
+ when(mScrimController.getBackScaling())
+ .thenReturn(mNotificationPanelViewController.SHADE_BACK_ANIM_MIN_SCALE);
+ assertThat(mQsController.calculateBottomCornerRadius(0.0f))
+ .isEqualTo(mQsController.getScrimCornerRadius());
+ }
+
+ @Test
+ public void calculateBottomCornerRadius_scrimScaleCutoff() {
+ float ratio = 1 / mQsController.calculateBottomRadiusProgress();
+ float cutoffScale = 1 - mNotificationPanelViewController.SHADE_BACK_ANIM_MIN_SCALE / ratio;
+ when(mScrimController.getBackScaling())
+ .thenReturn(cutoffScale);
+ assertThat(mQsController.calculateBottomCornerRadius(0.0f))
+ .isEqualTo(mQsController.getScrimCornerRadius());
+ }
+
private void lockScreen() {
mQsController.setBarState(KEYGUARD);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 69d03d9b0e4c..f8e1a9d12657 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -71,7 +71,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun upTransitionSceneKey_deviceLocked_lockScreen() =
testScope.runTest {
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
@@ -81,7 +81,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun upTransitionSceneKey_deviceUnlocked_gone() =
testScope.runTest {
val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
@@ -91,7 +91,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.unlockDevice()
runCurrent()
@@ -104,7 +104,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
- authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+ authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Pin(1234))
authenticationInteractor.lockDevice()
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 6a0e3c6d51eb..10aac4eb0a22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -47,6 +47,7 @@ import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -70,6 +71,7 @@ import com.android.systemui.statusbar.notification.collection.render.GroupExpans
import com.android.systemui.statusbar.notification.collection.render.NotifStats;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
@@ -105,6 +107,7 @@ import java.util.Optional;
public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private NotificationGutsManager mNotificationGutsManager;
+ @Mock private NotificationsController mNotificationsController;
@Mock private NotificationVisibilityProvider mVisibilityProvider;
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@@ -117,6 +120,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private SysuiStatusBarStateController mSysuiStatusBarStateController;
@Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private KeyguardInteractor mKeyguardInteractor;
@Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@Mock private MetricsLogger mMetricsLogger;
@Mock private DumpManager mDumpManager;
@@ -453,6 +457,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mNotificationStackScrollLayout,
true,
mNotificationGutsManager,
+ mNotificationsController,
mVisibilityProvider,
mHeadsUpManager,
mNotificationRoundnessManager,
@@ -463,6 +468,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mSysuiStatusBarStateController,
mKeyguardMediaController,
mKeyguardBypassController,
+ mKeyguardInteractor,
mZenModeController,
mNotificationLockscreenUserManager,
Optional.<NotificationListViewModel>empty(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index a4ee349f5b71..c0d98b2b2080 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -79,9 +79,9 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
+import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.FooterView;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -114,7 +114,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
private TestableResources mTestableResources;
@Rule public MockitoRule mockito = MockitoJUnit.rule();
- @Mock private CentralSurfaces mCentralSurfaces;
+ @Mock private NotificationsController mNotificationsController;
@Mock private SysuiStatusBarStateController mBarState;
@Mock private GroupMembershipManager mGroupMembershipManger;
@Mock private GroupExpansionManager mGroupExpansionManager;
@@ -181,7 +181,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mNotificationStackSizeCalculator);
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelfController(notificationShelfController);
- mStackScroller.setCentralSurfaces(mCentralSurfaces);
+ mStackScroller.setNotificationsController(mNotificationsController);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mStackScrollLayoutController.isHistoryEnabled()).thenReturn(true);
when(mStackScrollLayoutController.getNotificationRoundnessManager())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 551499e0fb55..7632d01d4d43 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -392,23 +392,32 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
@Test
public void testSnapchild_targetIsZero() {
- doNothing().when(mSwipeHelper).superSnapChild(mView, 0, 0);
- mSwipeHelper.snapChild(mView, 0, 0);
+ doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 0, 0);
+ mSwipeHelper.snapChild(mNotificationRow, 0, 0);
- verify(mCallback, times(1)).onDragCancelled(mView);
- verify(mSwipeHelper, times(1)).superSnapChild(mView, 0, 0);
+ verify(mCallback, times(1)).onDragCancelled(mNotificationRow);
+ verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 0, 0);
verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed();
}
@Test
public void testSnapchild_targetNotZero() {
+ doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 10, 0);
+ mSwipeHelper.snapChild(mNotificationRow, 10, 0);
+
+ verify(mCallback, times(1)).onDragCancelled(mNotificationRow);
+ verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 10, 0);
+ verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed();
+ }
+
+ @Test
+ public void testSnapchild_targetNotSwipeable() {
doNothing().when(mSwipeHelper).superSnapChild(mView, 10, 0);
mSwipeHelper.snapChild(mView, 10, 0);
- verify(mCallback, times(1)).onDragCancelled(mView);
- verify(mSwipeHelper, times(1)).superSnapChild(mView, 10, 0);
- verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed();
+ verify(mCallback).onDragCancelled(mView);
+ verify(mSwipeHelper, never()).superSnapChild(mView, 10, 0);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
index 4a3080050a37..442ba0977cf6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -68,6 +69,7 @@ class ActivityStarterImplTest : SysuiTestCase() {
@Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
@Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager
@Mock private lateinit var statusBarWindowController: StatusBarWindowController
+ @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
@@ -90,6 +92,7 @@ class ActivityStarterImplTest : SysuiTestCase() {
Lazy { keyguardViewMediator },
Lazy { shadeController },
Lazy { statusBarKeyguardViewManager },
+ Lazy { notifShadeWindowController },
activityLaunchAnimator,
context,
lockScreenUserManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index fd9f6a73aee4..4ed113fe1358 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -287,7 +287,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
@Mock private ScreenPinningRequest mScreenPinningRequest;
@Mock private PluginDependencyProvider mPluginDependencyProvider;
- @Mock private KeyguardDismissUtil mKeyguardDismissUtil;
@Mock private ExtensionController mExtensionController;
@Mock private UserInfoControllerImpl mUserInfoControllerImpl;
@Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
@@ -516,7 +515,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mInitController,
new Handler(TestableLooper.get(this).getLooper()),
mPluginDependencyProvider,
- mKeyguardDismissUtil,
mExtensionController,
mUserInfoControllerImpl,
mPhoneStatusBarPolicy,
@@ -1103,8 +1101,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
clearInvocations(mNotificationPanelViewController);
mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
- verify(mDozeServiceHost).stopDozing();
+ verify(mDozeServiceHost, never()).stopDozing();
verify(mNotificationPanelViewController).expand(eq(false));
+ mCentralSurfaces.mWakefulnessObserver.onFinishedWakingUp();
+ verify(mDozeServiceHost).stopDozing();
}
@Test
@@ -1118,6 +1118,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mCentralSurfaces.setBouncerShowing(true);
mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
verify(mNotificationPanelViewController, never()).expand(anyBoolean());
+ mCentralSurfaces.mWakefulnessObserver.onFinishedWakingUp();
+ verify(mDozeServiceHost).stopDozing();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
new file mode 100644
index 000000000000..b0aa2d3934cc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardDismissUtilTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class KeyguardDismissUtilTest extends SysuiTestCase {
+ @Mock
+ private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private SysuiStatusBarStateController mStatusBarStateController;
+ @Mock
+ private ActivityStarter mActivityStarter;
+ @Mock
+ private ActivityStarter.OnDismissAction mAction;
+
+ private KeyguardDismissUtil mKeyguardDismissUtil;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mKeyguardDismissUtil = new KeyguardDismissUtil(
+ mKeyguardStateController, mStatusBarStateController, mActivityStarter);
+ }
+
+ @Test
+ public void testSetLeaveOpenOnKeyguardHideWhenKeyGuardStateControllerIsShowing() {
+ doReturn(true).when(mKeyguardStateController).isShowing();
+
+ mKeyguardDismissUtil.executeWhenUnlocked(mAction, true /* requiresShadeOpen */,
+ true /* afterKeyguardGone */);
+
+ verify(mStatusBarStateController).setLeaveOpenOnKeyguardHide(true);
+
+ verify(mActivityStarter).dismissKeyguardThenExecute(mAction, null, true);
+
+ }
+
+ @Test
+ public void testSetLeaveOpenOnKeyguardHideWhenKeyGuardStateControllerIsNotShowing() {
+ doReturn(false).when(mKeyguardStateController).isShowing();
+
+ mKeyguardDismissUtil.executeWhenUnlocked(mAction, true /* requiresShadeOpen */,
+ true /* afterKeyguardGone */);
+
+ //no interaction with mStatusBarStateController
+ verify(mStatusBarStateController, times(0)).setLeaveOpenOnKeyguardHide(true);
+
+ verify(mActivityStarter).dismissKeyguardThenExecute(mAction, null, true);
+
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index e56f0d6b3b0f..8ad522ac3d6f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -135,6 +135,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@Mock private BouncerView mBouncerView;
@Mock private BouncerViewDelegate mBouncerViewDelegate;
@Mock private OnBackAnimationCallback mBouncerViewDelegateBackCallback;
+ @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
@Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private WindowInsetsController mWindowInsetsController;
@Mock private TaskbarDelegate mTaskbarDelegate;
@@ -168,7 +169,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM))
.thenReturn(true);
- when(mCentralSurfaces.getNotificationShadeWindowView())
+ when(mNotificationShadeWindowController.getWindowRootView())
.thenReturn(mNotificationShadeWindowView);
when(mNotificationShadeWindowView.getWindowInsetsController())
.thenReturn(mWindowInsetsController);
@@ -184,7 +185,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mDreamOverlayStateController,
mock(NavigationModeController.class),
mock(DockManager.class),
- mock(NotificationShadeWindowController.class),
+ mNotificationShadeWindowController,
mKeyguardStateController,
mock(NotificationMediaManager.class),
mKeyguardMessageAreaFactory,
@@ -352,6 +353,17 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ public void onPanelExpansionChanged_neverTranslatesBouncerWhenGoingAway() {
+ when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
+ mStatusBarKeyguardViewManager.onPanelExpansionChanged(
+ expansionEvent(
+ /* fraction= */ EXPANSION_VISIBLE,
+ /* expanded= */ true,
+ /* tracking= */ false));
+ verify(mPrimaryBouncerInteractor, never()).setPanelExpansion(anyFloat());
+ }
+
+ @Test
public void onPanelExpansionChanged_neverTranslatesBouncerWhenShowBouncer() {
// Since KeyguardBouncer.EXPANSION_VISIBLE = 0 panel expansion, if the unlock is dismissing
// the bouncer, there may be an onPanelExpansionChanged(0) call to collapse the panel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index d6ae2b711583..d44af885a27e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -73,6 +73,7 @@ import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -233,6 +234,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mCentralSurfaces,
mock(NotificationPresenter.class),
mock(ShadeViewController.class),
+ mock(NotificationShadeWindowController.class),
mActivityLaunchAnimator,
notificationAnimationProvider,
mock(LaunchFullScreenIntentProvider.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index fdfe028765ef..1724f27f63b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -44,7 +44,6 @@ import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeNotificationPresenter;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -122,7 +121,6 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mock(NotificationShadeWindowController.class),
mock(DynamicPrivacyController.class),
mKeyguardStateController,
- mock(KeyguardIndicationController.class),
mCentralSurfaces,
mock(LockscreenShadeTransitionController.class),
mCommandQueue,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index ea534bbd0794..2e9a6909e402 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.statusbar.LightRevealScrim
+import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.eq
@@ -65,6 +66,8 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
@Mock
private lateinit var shadeViewController: ShadeViewController
@Mock
+ private lateinit var notifShadeWindowController: NotificationShadeWindowController
+ @Mock
private lateinit var lightRevealScrim: LightRevealScrim
@Mock
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@@ -89,6 +92,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
keyguardStateController,
dagger.Lazy<DozeParameters> { dozeParameters },
globalSettings,
+ dagger.Lazy<NotificationShadeWindowController> { notifShadeWindowController },
interactionJankMonitor,
powerManager,
handler = handler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index f054422e6524..c4e419366759 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -40,6 +40,8 @@ class FakeMobileIconInteractor(
)
)
+ override val carrierNetworkChangeActive = MutableStateFlow(false)
+
override val mobileIsDefault = MutableStateFlow(true)
override val networkTypeIconGroup =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
new file mode 100644
index 000000000000..01c388a523e6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModelParameterizedTest.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.model
+
+import androidx.test.filters.SmallTest
+import com.android.settingslib.graph.SignalDrawable
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+@SmallTest
+@RunWith(Parameterized::class)
+internal class SignalIconModelParameterizedTest(private val testCase: TestCase) : SysuiTestCase() {
+ @Test
+ fun drawableFromModel_level0_numLevels4_noExclamation_notCarrierNetworkChange() {
+ val model =
+ SignalIconModel(
+ level = 0,
+ numberOfLevels = 4,
+ showExclamationMark = false,
+ carrierNetworkChange = false
+ )
+
+ val expected =
+ SignalDrawable.getState(/* level = */ 0, /* numLevels = */ 4, /* cutOut = */ false)
+
+ assertThat(model.toSignalDrawableState()).isEqualTo(expected)
+ }
+
+ @Test
+ fun runTest() {
+ val model = testCase.toSignalIconModel()
+ assertThat(model.toSignalDrawableState()).isEqualTo(testCase.expected)
+ }
+
+ internal data class TestCase(
+ val level: Int,
+ val numberOfLevels: Int,
+ val showExclamation: Boolean,
+ val carrierNetworkChange: Boolean,
+ val expected: Int,
+ ) {
+ fun toSignalIconModel() =
+ SignalIconModel(
+ level = level,
+ numberOfLevels = numberOfLevels,
+ showExclamationMark = showExclamation,
+ carrierNetworkChange = carrierNetworkChange,
+ )
+
+ override fun toString(): String =
+ "INPUT(level=$level," +
+ "numberOfLevels=$numberOfLevels," +
+ "showExclamation=$showExclamation," +
+ "carrierNetworkChange=$carrierNetworkChange)"
+ }
+
+ companion object {
+ @Parameters(name = "{0}") @JvmStatic fun data() = testData()
+
+ private fun testData(): Collection<TestCase> =
+ listOf(
+ TestCase(
+ level = 0,
+ numberOfLevels = 4,
+ showExclamation = false,
+ carrierNetworkChange = false,
+ expected = SignalDrawable.getState(0, 4, false)
+ ),
+ TestCase(
+ level = 0,
+ numberOfLevels = 4,
+ showExclamation = false,
+ carrierNetworkChange = true,
+ expected = SignalDrawable.getCarrierChangeState(4)
+ ),
+ TestCase(
+ level = 2,
+ numberOfLevels = 5,
+ showExclamation = false,
+ carrierNetworkChange = false,
+ expected = SignalDrawable.getState(2, 5, false)
+ ),
+ TestCase(
+ level = 2,
+ numberOfLevels = 5,
+ showExclamation = true,
+ carrierNetworkChange = false,
+ expected = SignalDrawable.getState(2, 5, true)
+ ),
+ TestCase(
+ level = 2,
+ numberOfLevels = 5,
+ showExclamation = true,
+ carrierNetworkChange = true,
+ expected = SignalDrawable.getCarrierChangeState(5)
+ ),
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index 2b7bc780f7c7..b5ab29d6217e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -273,6 +273,27 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
@Test
+ fun icon_usesCarrierNetworkState_whenInCarrierNetworkChangeMode() =
+ testScope.runTest {
+ var latest: SignalIconModel? = null
+ val job = underTest.icon.onEach { latest = it }.launchIn(this)
+
+ interactor.carrierNetworkChangeActive.value = true
+ interactor.level.value = 1
+
+ assertThat(latest!!.level).isEqualTo(1)
+ assertThat(latest!!.carrierNetworkChange).isTrue()
+
+ // SignalIconModel respects the current level
+ interactor.level.value = 2
+
+ assertThat(latest!!.level).isEqualTo(2)
+ assertThat(latest!!.carrierNetworkChange).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
fun contentDescription_notInService_usesNoPhone() =
testScope.runTest {
var latest: ContentDescription? = null
@@ -338,6 +359,20 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
@Test
+ fun networkType_null_whenCarrierNetworkChangeActive() =
+ testScope.runTest {
+ interactor.networkTypeIconGroup.value = NetworkTypeIconModel.DefaultIcon(THREE_G)
+ interactor.carrierNetworkChangeActive.value = true
+ interactor.mobileIsDefault.value = true
+ var latest: Icon? = null
+ val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+
+ assertThat(latest).isNull()
+
+ job.cancel()
+ }
+
+ @Test
fun networkTypeIcon_notNull_whenEnabled() =
testScope.runTest {
val expected =
@@ -617,13 +652,14 @@ class MobileIconViewModelTest : SysuiTestCase() {
}
private fun createAndSetViewModel() {
- underTest = MobileIconViewModel(
- SUB_1_ID,
- interactor,
- airplaneModeInteractor,
- constants,
- testScope.backgroundScope,
- )
+ underTest =
+ MobileIconViewModel(
+ SUB_1_ID,
+ interactor,
+ airplaneModeInteractor,
+ constants,
+ testScope.backgroundScope,
+ )
}
companion object {
@@ -632,10 +668,20 @@ class MobileIconViewModelTest : SysuiTestCase() {
/** Convenience constructor for these tests */
fun defaultSignal(level: Int = 1): SignalIconModel {
- return SignalIconModel(level, NUM_LEVELS, showExclamationMark = false)
+ return SignalIconModel(
+ level,
+ NUM_LEVELS,
+ showExclamationMark = false,
+ carrierNetworkChange = false,
+ )
}
fun emptySignal(): SignalIconModel =
- SignalIconModel(level = 0, numberOfLevels = NUM_LEVELS, showExclamationMark = true)
+ SignalIconModel(
+ level = 0,
+ numberOfLevels = NUM_LEVELS,
+ showExclamationMark = true,
+ carrierNetworkChange = false,
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 3b0d5120cca3..ae38958ecb44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -51,9 +51,11 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SmartReplyController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -107,14 +109,15 @@ public class SmartReplyViewTest extends SysuiTestCase {
private SmartReplyInflaterImpl mSmartReplyInflater;
private SmartActionInflaterImpl mSmartActionInflater;
+ private KeyguardDismissUtil mKeyguardDismissUtil;
@Mock private SmartReplyConstants mConstants;
@Mock private ActivityStarter mActivityStarter;
@Mock private HeadsUpManager mHeadsUpManager;
@Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
@Mock private SmartReplyController mSmartReplyController;
-
- private final KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil();
+ @Mock private KeyguardStateController mKeyguardStateController;
+ @Mock private SysuiStatusBarStateController mStatusBarStateController;
@Before
public void setUp() {
@@ -122,12 +125,15 @@ public class SmartReplyViewTest extends SysuiTestCase {
mReceiver = new BlockingQueueIntentReceiver();
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION),
Context.RECEIVER_EXPORTED_UNAUDITED);
- mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> action.onDismiss());
+
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
mDependency.injectMockDependency(ShadeController.class);
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
mDependency.injectTestDependency(ActivityStarter.class, mActivityStarter);
mDependency.injectTestDependency(SmartReplyConstants.class, mConstants);
+ mDependency.injectTestDependency(KeyguardStateController.class, mKeyguardStateController);
+ mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
+
// Any number of replies are fine.
when(mConstants.getMinNumSystemGeneratedReplies()).thenReturn(0);
@@ -153,6 +159,13 @@ public class SmartReplyViewTest extends SysuiTestCase {
mActionIcon = Icon.createWithResource(mContext, R.drawable.ic_person);
+ mKeyguardDismissUtil = new KeyguardDismissUtil(
+ mKeyguardStateController, mStatusBarStateController, mActivityStarter) {
+ public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
+ boolean requiresShadeOpen, boolean afterKeyguardGone) {
+ action.onDismiss();
+ }
+ };
mSmartReplyInflater = new SmartReplyInflaterImpl(
mConstants,
mKeyguardDismissUtil,
@@ -185,7 +198,17 @@ public class SmartReplyViewTest extends SysuiTestCase {
@Test
public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
- mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> { });
+ mKeyguardDismissUtil = new KeyguardDismissUtil(
+ mKeyguardStateController, mStatusBarStateController, mActivityStarter) {
+ public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
+ boolean requiresShadeOpen, boolean afterKeyguardGone) { }};
+ mSmartReplyInflater = new SmartReplyInflaterImpl(
+ mConstants,
+ mKeyguardDismissUtil,
+ mNotificationRemoteInputManager,
+ mSmartReplyController,
+ mContext);
+
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
@@ -196,9 +219,20 @@ public class SmartReplyViewTest extends SysuiTestCase {
@Test
public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
+ mKeyguardDismissUtil = new KeyguardDismissUtil(
+ mKeyguardStateController, mStatusBarStateController, mActivityStarter) {
+ public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
+ boolean requiresShadeOpen, boolean afterKeyguardGone) {
+ actionRef.set(action);
+ }
+ };
+ mSmartReplyInflater = new SmartReplyInflaterImpl(
+ mConstants,
+ mKeyguardDismissUtil,
+ mNotificationRemoteInputManager,
+ mSmartReplyController,
+ mContext);
- mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone)
- -> actionRef.set(action));
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index c7c6b945f09a..98bbb26eb703 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -24,6 +24,8 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.dagger.qualifiers.Main
@@ -60,6 +62,9 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
private lateinit var fakeWakeLock: WakeLockFake
+ private lateinit var fakeUiEventLogger: UiEventLoggerFake
+ private lateinit var uiEventLogger: TemporaryViewUiEventLogger
+
@Mock
private lateinit var logger: TemporaryViewLogger<ViewInfo>
@Mock
@@ -87,6 +92,9 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
fakeWakeLockBuilder = WakeLockFake.Builder(context)
fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
+ fakeUiEventLogger = UiEventLoggerFake()
+ uiEventLogger = TemporaryViewUiEventLogger(fakeUiEventLogger)
+
underTest = TestController(
context,
logger,
@@ -98,6 +106,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
powerManager,
fakeWakeLockBuilder,
fakeClock,
+ uiEventLogger,
)
underTest.start()
}
@@ -126,6 +135,8 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
underTest.displayView(info)
verify(logger).logViewAddition(info)
+ assertThat(fakeUiEventLogger.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
}
@Test
@@ -1029,6 +1040,9 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
verify(logger).logViewRemoval(DEFAULT_ID, reason)
verify(configurationController).removeCallback(any())
assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+ assertThat(fakeUiEventLogger.logs.size).isEqualTo(1)
+ assertThat(fakeUiEventLogger.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
}
@Test
@@ -1133,6 +1147,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
powerManager: PowerManager,
wakeLockBuilder: WakeLock.Builder,
systemClock: SystemClock,
+ uiEventLogger: TemporaryViewUiEventLogger,
) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger<ViewInfo>>(
context,
logger,
@@ -1145,6 +1160,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
R.layout.chipbar,
wakeLockBuilder,
systemClock,
+ uiEventLogger,
) {
var mostRecentViewInfo: ViewInfo? = null
@@ -1168,6 +1184,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() {
override val timeoutMs: Int = TIMEOUT_MS.toInt(),
override val id: String = DEFAULT_ID,
override val priority: ViewPriority = ViewPriority.NORMAL,
+ override val instanceId: InstanceId = InstanceId.fakeInstanceId(0),
) : TemporaryViewInfo()
inner class Listener : TemporaryViewDisplayController.Listener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
index 451424927b23..38c1a785d1e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.temporarydisplay
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.LogBuffer
@@ -50,6 +51,7 @@ class TemporaryViewLoggerTest : SysuiTestCase() {
override val priority: ViewPriority = ViewPriority.CRITICAL
override val windowTitle: String = "Test Window Title"
override val wakeReason: String = "wake reason"
+ override val instanceId: InstanceId = InstanceId.fakeInstanceId(0)
}
logger.logViewAddition(info)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
new file mode 100644
index 000000000000..f707a8dafeda
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class TemporaryViewUiEventLoggerTest : SysuiTestCase() {
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var logger: TemporaryViewUiEventLogger
+
+ @Before
+ fun setup() {
+ uiEventLoggerFake = UiEventLoggerFake()
+ logger = TemporaryViewUiEventLogger(uiEventLoggerFake)
+ }
+
+ @Test
+ fun testViewAdded() {
+ logger.logViewAdded(InstanceId.fakeInstanceId(123))
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+ }
+
+ @Test
+ fun testMultipleViewsAdded_differentInstanceIds() {
+ logger.logViewAdded(logger.getNewInstanceId())
+ logger.logViewAdded(logger.getNewInstanceId())
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+ assertThat(uiEventLoggerFake.eventId(1))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+ assertThat(uiEventLoggerFake.logs[0].instanceId.id)
+ .isNotEqualTo(uiEventLoggerFake.logs[1].instanceId.id)
+ }
+
+ @Test
+ fun testViewManuallyDismissed() {
+ logger.logViewManuallyDismissed(InstanceId.fakeInstanceId(123))
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED.id)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index d33271b9d88f..03834e057418 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -30,6 +30,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.core.animation.doOnCancel
import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -43,6 +44,8 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEvent
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
import com.android.systemui.temporarydisplay.ViewPriority
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
@@ -87,6 +90,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
private lateinit var fakeClock: FakeSystemClock
private lateinit var fakeExecutor: FakeExecutor
private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var uiEventLogger: TemporaryViewUiEventLogger
@Before
fun setUp() {
@@ -101,6 +105,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
uiEventLoggerFake = UiEventLoggerFake()
+ uiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
chipbarAnimator = TestChipbarAnimator()
underTest =
@@ -121,6 +126,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
vibratorHelper,
fakeWakeLockBuilder,
fakeClock,
+ uiEventLogger,
)
underTest.start()
}
@@ -632,7 +638,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
}
@Test
- fun swipeToDismiss_swipeOccurs_viewDismissed() {
+ fun swipeToDismiss_swipeOccurs_viewDismissed_manuallyDismissedLogged() {
underTest.displayView(
createChipbarInfo(
Icon.Resource(R.drawable.ic_cake, contentDescription = null),
@@ -649,6 +655,9 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
callbackCaptor.value.invoke(MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0))
verify(windowManager).removeView(view)
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+ assertThat(uiEventLoggerFake.eventId(1))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED.id)
}
@Test
@@ -665,6 +674,11 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
val callbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
verify(swipeGestureHandler).addOnGestureDetectedCallback(any(), capture(callbackCaptor))
+ // only one log for view addition
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+
// WHEN the view is updated to not allow swipe-to-dismiss
underTest.displayView(
createChipbarInfo(
@@ -683,6 +697,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
// THEN it is ignored and view isn't removed
verify(windowManager, never()).removeView(view)
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
}
private fun createChipbarInfo(
@@ -703,6 +718,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() {
timeoutMs = TIMEOUT,
id = DEVICE_ID,
priority = ViewPriority.NORMAL,
+ instanceId = InstanceId.fakeInstanceId(0),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index d9ee08157c84..813597a8b576 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -28,12 +28,10 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.WakefulnessLifecycle
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.shade.ShadeFoldAnimator
import com.android.systemui.shade.ShadeViewController
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.unfold.util.FoldableDeviceStates
@@ -80,8 +78,6 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
@Mock lateinit var viewTreeObserver: ViewTreeObserver
- @Mock private lateinit var commandQueue: CommandQueue
-
@Mock lateinit var shadeFoldAnimator: ShadeFoldAnimator
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
@@ -111,15 +107,10 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
onActionStarted.run()
}
- keyguardRepository = FakeKeyguardRepository()
val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
- val keyguardInteractor =
- KeyguardInteractor(
- repository = keyguardRepository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- )
+ val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ val keyguardInteractor = withDeps.keyguardInteractor
+ keyguardRepository = withDeps.repository
// Needs to be run on the main thread
runBlocking(IMMEDIATE) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
index 4a28cd1de255..56c624565971 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
@@ -4,7 +4,7 @@ import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionPr
class TestUnfoldTransitionProvider : UnfoldTransitionProgressProvider, TransitionProgressListener {
- private val listeners = arrayListOf<TransitionProgressListener>()
+ private val listeners = mutableListOf<TransitionProgressListener>()
override fun destroy() {
listeners.clear()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
index d3fdbd94a5ac..3dec45b4ff9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -20,10 +20,9 @@ import android.os.Vibrator
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.util.TestFoldProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
-import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -115,20 +114,4 @@ class UnfoldHapticsPlayerTest : SysuiTestCase() {
verify(vibrator).vibrate(any<VibrationEffect>())
}
-
- private class TestFoldProvider : FoldProvider {
- private val listeners = arrayListOf<FoldProvider.FoldCallback>()
-
- override fun registerCallback(callback: FoldProvider.FoldCallback, executor: Executor) {
- listeners += callback
- }
-
- override fun unregisterCallback(callback: FoldProvider.FoldCallback) {
- listeners -= callback
- }
-
- fun onFoldUpdate(isFolded: Boolean) {
- listeners.forEach { it.onFoldUpdated(isFolded) }
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
index e2aef31b4f10..e461e3f7fb1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
@@ -74,6 +74,11 @@ class TestUnfoldProgressListener : UnfoldTransitionProgressProvider.TransitionPr
currentRecording?.assertLastProgress(progress) ?: error("unfold not in progress.")
}
+ fun clear() {
+ currentRecording = null
+ recordings.clear()
+ }
+
class UnfoldTransitionRecording {
private val progressHistory: MutableList<Float> = arrayListOf()
private var finishingInvocations: Int = 0
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt
new file mode 100644
index 000000000000..35df35ccfe9c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+import com.android.systemui.unfold.updates.FoldProvider
+import java.util.concurrent.Executor
+
+class TestFoldProvider : FoldProvider {
+ private val listeners = arrayListOf<FoldProvider.FoldCallback>()
+
+ override fun registerCallback(callback: FoldProvider.FoldCallback, executor: Executor) {
+ listeners += callback
+ }
+
+ override fun unregisterCallback(callback: FoldProvider.FoldCallback) {
+ listeners -= callback
+ }
+
+ fun onFoldUpdate(isFolded: Boolean) {
+ listeners.forEach { it.onFoldUpdated(isFolded) }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
new file mode 100644
index 000000000000..4a38fc069d9f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.progress.TestUnfoldProgressListener
+import com.google.common.util.concurrent.MoreExecutors
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class UnfoldOnlyProgressProviderTest : SysuiTestCase() {
+
+ private val listener = TestUnfoldProgressListener()
+ private val sourceProvider = TestUnfoldTransitionProvider()
+
+ private val foldProvider = TestFoldProvider()
+
+ private lateinit var progressProvider: UnfoldOnlyProgressProvider
+
+ @Before
+ fun setUp() {
+ progressProvider =
+ UnfoldOnlyProgressProvider(foldProvider, MoreExecutors.directExecutor(), sourceProvider)
+
+ progressProvider.addCallback(listener)
+ }
+
+ @Test
+ fun unfolded_unfoldAnimationFinished_propagatesEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+
+ with(listener.ensureTransitionFinished()) {
+ assertLastProgress(0.5f)
+ }
+ }
+
+ @Test
+ fun unfoldedWithAnimation_foldAnimation_doesNotPropagateEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+ listener.clear()
+
+ // Fold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+
+ listener.assertNotStarted()
+ }
+
+ @Test
+ fun unfoldedWithAnimation_foldAnimationSeveralTimes_doesNotPropagateEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+ listener.clear()
+
+ // Start and stop fold animation several times
+ repeat(3) {
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+ }
+
+ listener.assertNotStarted()
+ }
+
+ @Test
+ fun unfoldedAgainAfterFolding_propagatesEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+
+ // Fold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+ foldProvider.onFoldUpdate(isFolded = true)
+
+ listener.clear()
+
+ // Second unfold animation after folding
+ foldProvider.onFoldUpdate(isFolded = false)
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.1f)
+ sourceProvider.onTransitionFinished()
+
+ with(listener.ensureTransitionFinished()) {
+ assertLastProgress(0.1f)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index ca83d49b19ca..3fbbeda8f74d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -39,12 +39,10 @@ import com.android.systemui.common.shared.model.Text
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.user.UserSwitchDialogController
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -97,7 +95,6 @@ class UserInteractorTest : SysuiTestCase() {
@Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: UserInteractor
@@ -126,8 +123,9 @@ class UserInteractorTest : SysuiTestCase() {
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.FACE_AUTH_REFACTOR, true)
}
+ val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ keyguardRepository = reply.repository
userRepository = FakeUserRepository()
- keyguardRepository = FakeKeyguardRepository()
telephonyRepository = FakeTelephonyRepository()
val testDispatcher = StandardTestDispatcher()
testScope = TestScope(testDispatcher)
@@ -142,13 +140,7 @@ class UserInteractorTest : SysuiTestCase() {
applicationContext = context,
repository = userRepository,
activityStarter = activityStarter,
- keyguardInteractor =
- KeyguardInteractor(
- repository = keyguardRepository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- ),
+ keyguardInteractor = reply.keyguardInteractor,
manager = manager,
headlessSystemUserMode = headlessSystemUserMode,
applicationScope = testScope.backgroundScope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index fd8c6c76720b..9cb26e05887d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -32,11 +32,8 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -80,13 +77,11 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
@Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: StatusBarUserChipViewModel
private val userRepository = FakeUserRepository()
- private val keyguardRepository = FakeKeyguardRepository()
private lateinit var guestUserInteractor: GuestUserInteractor
private lateinit var refreshUsersScheduler: RefreshUsersScheduler
@@ -250,12 +245,8 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
repository = userRepository,
activityStarter = activityStarter,
keyguardInteractor =
- KeyguardInteractor(
- repository = keyguardRepository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- ),
+ KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ .keyguardInteractor,
featureFlags = featureFlags,
manager = manager,
headlessSystemUserMode = headlessSystemUserMode,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 91550844ceca..e3f9fac27815 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -30,11 +30,9 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -79,7 +77,6 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
@Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
- @Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: UserSwitcherViewModel
@@ -112,7 +109,6 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
)
}
- keyguardRepository = FakeKeyguardRepository()
val refreshUsersScheduler =
RefreshUsersScheduler(
applicationScope = testScope.backgroundScope,
@@ -140,38 +136,35 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.FACE_AUTH_REFACTOR, true)
}
+ val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ keyguardRepository = reply.repository
+
underTest =
UserSwitcherViewModel(
- userInteractor =
- UserInteractor(
- applicationContext = context,
- repository = userRepository,
- activityStarter = activityStarter,
- keyguardInteractor =
- KeyguardInteractor(
- repository = keyguardRepository,
- commandQueue = commandQueue,
- featureFlags = featureFlags,
- bouncerRepository = FakeKeyguardBouncerRepository(),
- ),
- featureFlags = featureFlags,
- manager = manager,
- headlessSystemUserMode = headlessSystemUserMode,
- applicationScope = testScope.backgroundScope,
- telephonyInteractor =
- TelephonyInteractor(
- repository = FakeTelephonyRepository(),
- ),
- broadcastDispatcher = fakeBroadcastDispatcher,
- keyguardUpdateMonitor = keyguardUpdateMonitor,
- backgroundDispatcher = testDispatcher,
- activityManager = activityManager,
- refreshUsersScheduler = refreshUsersScheduler,
- guestUserInteractor = guestUserInteractor,
- uiEventLogger = uiEventLogger,
- ),
- guestUserInteractor = guestUserInteractor,
- )
+ userInteractor =
+ UserInteractor(
+ applicationContext = context,
+ repository = userRepository,
+ activityStarter = activityStarter,
+ keyguardInteractor = reply.keyguardInteractor,
+ featureFlags = featureFlags,
+ manager = manager,
+ headlessSystemUserMode = headlessSystemUserMode,
+ applicationScope = testScope.backgroundScope,
+ telephonyInteractor =
+ TelephonyInteractor(
+ repository = FakeTelephonyRepository(),
+ ),
+ broadcastDispatcher = fakeBroadcastDispatcher,
+ keyguardUpdateMonitor = keyguardUpdateMonitor,
+ backgroundDispatcher = testDispatcher,
+ activityManager = activityManager,
+ refreshUsersScheduler = refreshUsersScheduler,
+ guestUserInteractor = guestUserInteractor,
+ uiEventLogger = uiEventLogger,
+ ),
+ guestUserInteractor = guestUserInteractor,
+ )
}
@Test
@@ -323,7 +316,7 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
setUsers(count = 2)
val isFinishRequested = mutableListOf<Boolean>()
val job =
- launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+ launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
assertThat(isFinishRequested.last()).isFalse()
underTest.onCancelButtonClicked()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 47a86b1fca5c..2158396b4e15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -320,7 +320,7 @@ public class BubblesTest extends SysuiTestCase {
mColorExtractor, mDumpManager, mKeyguardStateController,
mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager,
mShadeWindowLogger);
- mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
+ mNotificationShadeWindowController.setWindowRootView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt
index b2a1668df7aa..b2a1668df7aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index b52a76839a99..f6cbb072495f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -81,7 +81,7 @@ class FakeKeyguardRepository : KeyguardRepository {
MutableStateFlow(
WakefulnessModel(WakefulnessState.ASLEEP, WakeSleepReason.OTHER, WakeSleepReason.OTHER)
)
- override val wakefulness: Flow<WakefulnessModel> = _wakefulnessModel
+ override val wakefulness = _wakefulnessModel
private val _isUdfpsSupported = MutableStateFlow(false)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
new file mode 100644
index 000000000000..c7ca7ceb516e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeCommandQueue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+
+/**
+ * Simply put, I got tired of adding a constructor argument and then having to tweak dozens of
+ * files. This should alleviate some of the burden by providing defaults for testing.
+ */
+object KeyguardInteractorFactory {
+
+ @JvmOverloads
+ @JvmStatic
+ fun create(
+ featureFlags: FakeFeatureFlags = createFakeFeatureFlags(),
+ repository: FakeKeyguardRepository = FakeKeyguardRepository(),
+ commandQueue: FakeCommandQueue = FakeCommandQueue(),
+ bouncerRepository: FakeKeyguardBouncerRepository = FakeKeyguardBouncerRepository(),
+ configurationRepository: FakeConfigurationRepository = FakeConfigurationRepository(),
+ ): WithDependencies {
+ return WithDependencies(
+ repository = repository,
+ commandQueue = commandQueue,
+ featureFlags = featureFlags,
+ bouncerRepository = bouncerRepository,
+ configurationRepository = configurationRepository,
+ KeyguardInteractor(
+ repository = repository,
+ commandQueue = commandQueue,
+ featureFlags = featureFlags,
+ bouncerRepository = bouncerRepository,
+ configurationRepository = configurationRepository,
+ )
+ )
+ }
+
+ /** Provide defaults, otherwise tests will throw an error */
+ fun createFakeFeatureFlags(): FakeFeatureFlags {
+ return FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, false) }
+ }
+
+ data class WithDependencies(
+ val repository: FakeKeyguardRepository,
+ val commandQueue: FakeCommandQueue,
+ val featureFlags: FakeFeatureFlags,
+ val bouncerRepository: FakeKeyguardBouncerRepository,
+ val configurationRepository: FakeConfigurationRepository,
+ val keyguardInteractor: KeyguardInteractor,
+ )
+}
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index f31ca8178eb6..c2ebddf00fb4 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -2057,7 +2057,11 @@ public class CameraExtensionsProxyService extends Service {
mIsImageValid = false;
if (mGraphicBuffer != null) {
- ImageReader.unlockGraphicBuffer(mGraphicBuffer);
+ try {
+ ImageReader.unlockGraphicBuffer(mGraphicBuffer);
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ }
mGraphicBuffer.destroy();
mGraphicBuffer = null;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ad038d1c0361..fdb28ba9103e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4006,17 +4006,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public boolean registerProxyForDisplay(IAccessibilityServiceClient client, int displayId)
throws RemoteException {
- mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.CREATE_VIRTUAL_DEVICE);
+ mSecurityPolicy.checkForAccessibilityPermissionOrRole();
if (client == null) {
return false;
}
if (displayId < 0) {
throw new IllegalArgumentException("The display id " + displayId + " is invalid.");
}
- if (displayId == Display.DEFAULT_DISPLAY) {
- throw new IllegalArgumentException("The default display cannot be proxy-ed.");
- }
if (!isTrackedDisplay(displayId)) {
throw new IllegalArgumentException("The display " + displayId + " does not exist or is"
+ " not tracked by accessibility.");
@@ -4025,6 +4022,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
throw new IllegalArgumentException("The display " + displayId + " is already being"
+ " proxy-ed");
}
+ if (!mProxyManager.displayBelongsToCaller(Binder.getCallingUid(), displayId)) {
+ throw new SecurityException("The display " + displayId + " does not belong to"
+ + " the caller.");
+ }
final long identity = Binder.clearCallingIdentity();
try {
@@ -4042,8 +4043,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public boolean unregisterProxyForDisplay(int displayId) {
- mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.CREATE_VIRTUAL_DEVICE);
+ mSecurityPolicy.checkForAccessibilityPermissionOrRole();
final long identity = Binder.clearCallingIdentity();
try {
return mProxyManager.unregisterProxy(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
index 93356263b897..f45fa921c4a2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
@@ -18,6 +18,7 @@ package com.android.server.accessibility;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_FAIL_BY_ADMIN;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_SUCCESS;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -25,6 +26,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.app.role.RoleManager;
import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
@@ -675,6 +677,42 @@ public class AccessibilitySecurityPolicy {
}
/**
+ * Throws a SecurityException if the caller has neither the MANAGE_ACCESSIBILITY permission nor
+ * the COMPANION_DEVICE_APP_STREAMING role.
+ */
+ public void checkForAccessibilityPermissionOrRole() {
+ final boolean canManageAccessibility =
+ mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
+ == PackageManager.PERMISSION_GRANTED;
+ if (canManageAccessibility) {
+ return;
+ }
+ final int callingUid = Binder.getCallingUid();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+ if (roleManager != null) {
+ final List<String> holders = roleManager.getRoleHoldersAsUser(
+ DEVICE_PROFILE_APP_STREAMING, UserHandle.getUserHandleForUid(callingUid));
+ final String[] packageNames = mPackageManager.getPackagesForUid(callingUid);
+ if (packageNames != null) {
+ for (String packageName : packageNames) {
+ if (holders.contains(packageName)) {
+ return;
+ }
+ }
+ }
+ }
+ throw new SecurityException(
+ "Cannot register a proxy for a device without the "
+ + "android.app.role.COMPANION_DEVICE_APP_STREAMING role or the"
+ + " MANAGE_ACCESSIBILITY permission.");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Called after a service was bound or unbound. Checks the current bound accessibility
* services and updates alarms.
*
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
index 6dc8fb347904..70882c6471de 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
@@ -24,6 +24,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityTrace;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.annotation.NonNull;
+import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
import android.content.ComponentName;
import android.content.Context;
@@ -319,6 +320,25 @@ public class ProxyManager {
return isTrackingDeviceId;
}
+ /** Returns true if the display belongs to one of the caller's virtual devices. */
+ public boolean displayBelongsToCaller(int callingUid, int proxyDisplayId) {
+ final VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class);
+ final VirtualDeviceManagerInternal localVdm = getLocalVdm();
+ if (vdm == null || localVdm == null) {
+ return false;
+ }
+ final List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
+ for (VirtualDevice device : virtualDevices) {
+ if (localVdm.getDisplayIdsForDevice(device.getDeviceId()).contains(proxyDisplayId)) {
+ final int ownerUid = localVdm.getDeviceOwnerUid(device.getDeviceId());
+ if (callingUid == ownerUid) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Sends AccessibilityEvents to a proxy given the event's displayId.
*/
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java
index 8e1aa38be9e8..41c3dcb3e48e 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationScaleProvider.java
@@ -16,6 +16,9 @@
package com.android.server.accessibility.magnification;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MAX_VALUE;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MIN_VALUE;
+
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
@@ -37,8 +40,9 @@ public class MagnificationScaleProvider {
@VisibleForTesting
protected static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
- public static final float MIN_SCALE = 1.0f;
- public static final float MAX_SCALE = 8.0f;
+
+ public static final float MIN_SCALE = SCALE_MIN_VALUE;
+ public static final float MAX_SCALE = SCALE_MAX_VALUE;
private final Context mContext;
// Stores the scale for non-default displays.
@@ -134,6 +138,6 @@ public class MagnificationScaleProvider {
}
static float constrainScale(float scale) {
- return MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ return MathUtils.constrain(scale, SCALE_MIN_VALUE, SCALE_MAX_VALUE);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index fc758cba617f..1a57bc1b7a0d 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -761,6 +761,18 @@ public final class AutofillManagerService
}
// Called by Shell command
+ boolean isFieldDetectionServiceEnabledForUser(@UserIdInt int userId) {
+ enforceCallingPermissionForManagement();
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
+ if (service != null) {
+ return service.isPccClassificationEnabled();
+ }
+ }
+ return false;
+ }
+
+ // Called by Shell command
String getFieldDetectionServiceName(@UserIdInt int userId) {
enforceCallingPermissionForManagement();
return mFieldClassificationResolver.readServiceName(userId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index cd6de8749f47..c66fb81f51c6 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -26,7 +26,6 @@ import android.os.RemoteCallback;
import android.os.ShellCommand;
import android.os.UserHandle;
import android.service.autofill.AutofillFieldClassificationService.Scores;
-import android.text.TextUtils;
import android.view.autofill.AutofillManager;
import com.android.internal.os.IResultReceiver;
@@ -348,9 +347,7 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand {
private int isFieldDetectionServiceEnabled(PrintWriter pw) {
final int userId = getNextIntArgRequired();
- String name = mService.getFieldDetectionServiceName(userId);
- boolean pccFlagEnabled = mService.isPccClassificationFlagEnabled();
- boolean enabled = (!TextUtils.isEmpty(name)) && pccFlagEnabled;
+ boolean enabled = mService.isFieldDetectionServiceEnabledForUser(userId);
pw.println(enabled);
return 0;
}
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java
new file mode 100644
index 000000000000..7351ef59feca
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.util.Slog;
+import android.view.autofill.AutofillId;
+import android.view.inputmethod.InlineSuggestionsRequest;
+
+import java.lang.ref.WeakReference;
+import java.util.function.Consumer;
+
+final class InlineSuggestionRendorInfoCallbackOnResultListener implements
+ RemoteCallback.OnResultListener{
+ private static final String TAG = "InlineSuggestionRendorInfoCallbackOnResultListener";
+
+ private final int mRequestIdCopy;
+ private final AutofillId mFocusedId;
+ private final WeakReference<Session> mSessionWeakReference;
+ private final Consumer<InlineSuggestionsRequest> mInlineSuggestionsRequestConsumer;
+
+ InlineSuggestionRendorInfoCallbackOnResultListener(WeakReference<Session> sessionWeakReference,
+ int requestIdCopy,
+ Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer,
+ AutofillId focusedId) {
+ this.mRequestIdCopy = requestIdCopy;
+ this.mInlineSuggestionsRequestConsumer = inlineSuggestionsRequestConsumer;
+ this.mSessionWeakReference = sessionWeakReference;
+ this.mFocusedId = focusedId;
+ }
+ public void onResult(@Nullable Bundle result) {
+ Session session = this.mSessionWeakReference.get();
+ if (session == null) {
+ Slog.wtf(TAG, "Session is null before trying to call onResult");
+ return;
+ }
+ synchronized (session.mLock) {
+ if (session.mDestroyed) {
+ Slog.wtf(TAG, "Session is destroyed before trying to call onResult");
+ return;
+ }
+ session.mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
+ this.mFocusedId,
+ session.inlineSuggestionsRequestCacheDecorator(
+ this.mInlineSuggestionsRequestConsumer, this.mRequestIdCopy),
+ result);
+ }
+ }
+}
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionRequestConsumer.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionRequestConsumer.java
new file mode 100644
index 000000000000..a3efb25a5735
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionRequestConsumer.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.util.Slog;
+import android.view.inputmethod.InlineSuggestionsRequest;
+
+import java.lang.ref.WeakReference;
+import java.util.function.Consumer;
+
+class InlineSuggestionRequestConsumer implements Consumer<InlineSuggestionsRequest> {
+
+ static final String TAG = "InlineSuggestionRequestConsumer";
+
+ private final WeakReference<Session.AssistDataReceiverImpl> mAssistDataReceiverWeakReference;
+ private final WeakReference<ViewState> mViewStateWeakReference;
+
+ InlineSuggestionRequestConsumer(WeakReference<Session.AssistDataReceiverImpl>
+ assistDataReceiverWeakReference,
+ WeakReference<ViewState> viewStateWeakReference) {
+ mAssistDataReceiverWeakReference = assistDataReceiverWeakReference;
+ mViewStateWeakReference = viewStateWeakReference;
+ }
+
+ @Override
+ public void accept(InlineSuggestionsRequest inlineSuggestionsRequest) {
+ Session.AssistDataReceiverImpl assistDataReceiver = mAssistDataReceiverWeakReference.get();
+ ViewState viewState = mViewStateWeakReference.get();
+ if (assistDataReceiver == null) {
+ Slog.wtf(TAG, "assistDataReceiver is null when accepting new inline suggestion"
+ + "requests");
+ return;
+ }
+
+ if (viewState == null) {
+ Slog.wtf(TAG, "view state is null when accepting new inline suggestion requests");
+ return;
+ }
+ assistDataReceiver.handleInlineSuggestionRequest(inlineSuggestionsRequest, viewState);
+ }
+}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 0a8f474fd4cc..563e431b5737 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -184,6 +184,7 @@ import com.android.server.wm.ActivityTaskManagerInternal;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -224,6 +225,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
private static final String PCC_HINTS_DELIMITER = ",";
+ public static final String EXTRA_KEY_DETECTIONS = "detections";
final Object mLock;
@@ -321,7 +323,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
* Id of the View currently being displayed.
*/
@GuardedBy("mLock")
- @Nullable private AutofillId mCurrentViewId;
+ private @Nullable AutofillId mCurrentViewId;
@GuardedBy("mLock")
private IAutoFillManagerClient mClient;
@@ -369,7 +371,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private Bundle mClientState;
@GuardedBy("mLock")
- private boolean mDestroyed;
+ boolean mDestroyed;
/**
* Helper used to handle state of Save UI when it must be hiding to show a custom description
@@ -448,7 +450,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private ArrayList<AutofillId> mAugmentedAutofillableIds;
@NonNull
- private final AutofillInlineSessionController mInlineSessionController;
+ final AutofillInlineSessionController mInlineSessionController;
/**
* Receiver of assist data from the app's {@link Activity}.
@@ -612,7 +614,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
* TODO(b/151867668): improve how asynchronous data dependencies are handled, without using
* CountDownLatch.
*/
- private final class AssistDataReceiverImpl extends IAssistDataReceiver.Stub {
+ final class AssistDataReceiverImpl extends IAssistDataReceiver.Stub {
@GuardedBy("mLock")
private boolean mWaitForInlineRequest;
@GuardedBy("mLock")
@@ -627,17 +629,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mPendingFillRequest = null;
mWaitForInlineRequest = isInlineRequest;
mPendingInlineSuggestionsRequest = null;
- return isInlineRequest ? (inlineSuggestionsRequest) -> {
- synchronized (mLock) {
- if (!mWaitForInlineRequest || mPendingInlineSuggestionsRequest != null) {
- return;
- }
- mWaitForInlineRequest = inlineSuggestionsRequest != null;
- mPendingInlineSuggestionsRequest = inlineSuggestionsRequest;
- maybeRequestFillLocked();
- viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
+ if (isInlineRequest) {
+ WeakReference<AssistDataReceiverImpl> assistDataReceiverWeakReference =
+ new WeakReference<AssistDataReceiverImpl>(this);
+ WeakReference<ViewState> viewStateWeakReference =
+ new WeakReference<ViewState>(viewState);
+ return new InlineSuggestionRequestConsumer(assistDataReceiverWeakReference,
+ viewStateWeakReference);
+ }
+ return null;
+ }
+
+ void handleInlineSuggestionRequest(InlineSuggestionsRequest inlineSuggestionsRequest,
+ ViewState viewState) {
+ synchronized (mLock) {
+ if (!mWaitForInlineRequest || mPendingInlineSuggestionsRequest != null) {
+ return;
}
- } : null;
+ mWaitForInlineRequest = inlineSuggestionsRequest != null;
+ mPendingInlineSuggestionsRequest = inlineSuggestionsRequest;
+ maybeRequestFillLocked();
+ viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
+ }
}
@GuardedBy("mLock")
@@ -1224,24 +1237,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final RemoteInlineSuggestionRenderService remoteRenderService =
mService.getRemoteInlineSuggestionRenderServiceLocked();
if (mSessionFlags.mInlineSupportedByService
- && remoteRenderService != null
- && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
+ && remoteRenderService != null
+ && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
+
Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer =
mAssistReceiver.newAutofillRequestLocked(viewState,
/* isInlineRequest= */ true);
+
if (inlineSuggestionsRequestConsumer != null) {
- final AutofillId focusedId = mCurrentViewId;
final int requestIdCopy = requestId;
+ final AutofillId focusedId = mCurrentViewId;
+
+ WeakReference sessionWeakReference = new WeakReference<Session>(this);
+ InlineSuggestionRendorInfoCallbackOnResultListener
+ inlineSuggestionRendorInfoCallbackOnResultListener =
+ new InlineSuggestionRendorInfoCallbackOnResultListener(
+ sessionWeakReference,
+ requestIdCopy,
+ inlineSuggestionsRequestConsumer,
+ focusedId);
+ RemoteCallback inlineSuggestionRendorInfoCallback = new RemoteCallback(
+ inlineSuggestionRendorInfoCallbackOnResultListener, mHandler);
+
remoteRenderService.getInlineSuggestionsRendererInfo(
- new RemoteCallback((extras) -> {
- synchronized (mLock) {
- mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
- focusedId, inlineSuggestionsRequestCacheDecorator(
- inlineSuggestionsRequestConsumer, requestIdCopy),
- extras);
- }
- }, mHandler)
- );
+ inlineSuggestionRendorInfoCallback);
viewState.setState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
}
} else {
@@ -3646,6 +3665,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final ArrayList<FillContext> contexts = mergePreviousSessionLocked( /* forSave= */ true);
+ FieldClassificationResponse fieldClassificationResponse =
+ mClassificationState.mLastFieldClassificationResponse;
+ if (mService.isPccClassificationEnabled()
+ && fieldClassificationResponse != null
+ && !fieldClassificationResponse.getClassifications().isEmpty()) {
+ if (mClientState == null) {
+ mClientState = new Bundle();
+ }
+ mClientState.putParcelableArrayList(EXTRA_KEY_DETECTIONS, new ArrayList<>(
+ fieldClassificationResponse.getClassifications()));
+ }
final SaveRequest saveRequest =
new SaveRequest(contexts, mClientState, mSelectedDatasetIds);
mRemoteFillService.onSaveRequest(saveRequest);
@@ -4827,16 +4857,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return null;
}
- final boolean isWhitelisted = mService
+ final boolean isAllowlisted = mService
.isWhitelistedForAugmentedAutofillLocked(mComponentName);
- if (!isWhitelisted) {
+ if (!isAllowlisted) {
if (sVerbose) {
Slog.v(TAG, "triggerAugmentedAutofillLocked(): "
+ ComponentName.flattenToShortString(mComponentName) + " not whitelisted ");
}
logAugmentedAutofillRequestLocked(mode, remoteService.getComponentName(),
- mCurrentViewId, isWhitelisted, /* isInline= */ null);
+ mCurrentViewId, isAllowlisted, /* isInline= */ null);
return null;
}
@@ -4869,32 +4899,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final AutofillId focusedId = mCurrentViewId;
- final Function<InlineFillUi, Boolean> inlineSuggestionsResponseCallback =
- response -> {
- synchronized (mLock) {
- return mInlineSessionController.setInlineFillUiLocked(response);
- }
- };
final Consumer<InlineSuggestionsRequest> requestAugmentedAutofill =
- (inlineSuggestionsRequest) -> {
- synchronized (mLock) {
- logAugmentedAutofillRequestLocked(mode, remoteService.getComponentName(),
- focusedId, isWhitelisted, inlineSuggestionsRequest != null);
- remoteService.onRequestAutofillLocked(id, mClient,
- taskId, mComponentName, mActivityToken,
- AutofillId.withoutSession(focusedId), currentValue,
- inlineSuggestionsRequest, inlineSuggestionsResponseCallback,
- /*onErrorCallback=*/ () -> {
- synchronized (mLock) {
- cancelAugmentedAutofillLocked();
-
- // Also cancel augmented in IME
- mInlineSessionController.setInlineFillUiLocked(
- InlineFillUi.emptyUi(mCurrentViewId));
- }
- }, mService.getRemoteInlineSuggestionRenderServiceLocked(), userId);
- }
- };
+ new AugmentedAutofillInlineSuggestionRequestConsumer(
+ this, focusedId, isAllowlisted, mode, currentValue);
// When the inline suggestion render service is available and the view is focused, there
// are 3 cases when augmented autofill should ask IME for inline suggestion request,
@@ -4912,14 +4919,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|| mSessionFlags.mExpiredResponse)
&& (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill");
- remoteRenderService.getInlineSuggestionsRendererInfo(new RemoteCallback(
- (extras) -> {
- synchronized (mLock) {
- mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
- focusedId, /*requestConsumer=*/ requestAugmentedAutofill,
- extras);
- }
- }, mHandler));
+ remoteRenderService.getInlineSuggestionsRendererInfo(
+ new RemoteCallback(
+ new AugmentedAutofillInlineSuggestionRendererOnResultListener(
+ this, focusedId, requestAugmentedAutofill),
+ mHandler));
} else {
requestAugmentedAutofill.accept(
mInlineSessionController.getInlineSuggestionsRequestLocked().orElse(null));
@@ -4930,6 +4934,169 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return mAugmentedAutofillDestroyer;
}
+ private static class AugmentedAutofillInlineSuggestionRendererOnResultListener
+ implements RemoteCallback.OnResultListener {
+
+ WeakReference<Session> mSessionWeakRef;
+ final AutofillId mFocusedId;
+ Consumer<InlineSuggestionsRequest> mRequestAugmentedAutofill;
+
+ AugmentedAutofillInlineSuggestionRendererOnResultListener(
+ Session session,
+ AutofillId focussedId,
+ Consumer<InlineSuggestionsRequest> requestAugmentedAutofill) {
+ mSessionWeakRef = new WeakReference<>(session);
+ mFocusedId = focussedId;
+ mRequestAugmentedAutofill = requestAugmentedAutofill;
+ }
+
+ @Override
+ public void onResult(@Nullable Bundle result) {
+ Session session = mSessionWeakRef.get();
+
+ if (logIfSessionNull(
+ session, "AugmentedAutofillInlineSuggestionRendererOnResultListener:")) {
+ return;
+ }
+ synchronized (session.mLock) {
+ session.mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
+ mFocusedId, /*requestConsumer=*/ mRequestAugmentedAutofill,
+ result);
+ }
+ }
+ }
+
+ private static class AugmentedAutofillInlineSuggestionRequestConsumer
+ implements Consumer<InlineSuggestionsRequest> {
+
+ WeakReference<Session> mSessionWeakRef;
+ final AutofillId mFocusedId;
+ final boolean mIsAllowlisted;
+ final int mMode;
+ final AutofillValue mCurrentValue;
+
+ AugmentedAutofillInlineSuggestionRequestConsumer(
+ Session session,
+ AutofillId focussedId,
+ boolean isAllowlisted,
+ int mode,
+ AutofillValue currentValue) {
+ mSessionWeakRef = new WeakReference<>(session);
+ mFocusedId = focussedId;
+ mIsAllowlisted = isAllowlisted;
+ mMode = mode;
+ mCurrentValue = currentValue;
+
+ }
+ @Override
+ public void accept(InlineSuggestionsRequest inlineSuggestionsRequest) {
+ Session session = mSessionWeakRef.get();
+
+ if (logIfSessionNull(
+ session, "AugmentedAutofillInlineSuggestionRequestConsumer:")) {
+ return;
+ }
+ session.onAugmentedAutofillInlineSuggestionAccept(
+ inlineSuggestionsRequest, mFocusedId, mIsAllowlisted, mMode, mCurrentValue);
+
+ }
+ }
+
+ private static class AugmentedAutofillInlineSuggestionsResponseCallback
+ implements Function<InlineFillUi, Boolean> {
+
+ WeakReference<Session> mSessionWeakRef;
+
+ AugmentedAutofillInlineSuggestionsResponseCallback(Session session) {
+ this.mSessionWeakRef = new WeakReference<>(session);
+ }
+
+ @Override
+ public Boolean apply(InlineFillUi inlineFillUi) {
+ Session session = mSessionWeakRef.get();
+
+ if (logIfSessionNull(
+ session, "AugmentedAutofillInlineSuggestionsResponseCallback:")) {
+ return false;
+ }
+
+ synchronized (session.mLock) {
+ return session.mInlineSessionController.setInlineFillUiLocked(inlineFillUi);
+ }
+ }
+ }
+
+ private static class AugmentedAutofillErrorCallback implements Runnable {
+
+ WeakReference<Session> mSessionWeakRef;
+
+ AugmentedAutofillErrorCallback(Session session) {
+ this.mSessionWeakRef = new WeakReference<>(session);
+ }
+
+ @Override
+ public void run() {
+ Session session = mSessionWeakRef.get();
+
+ if (logIfSessionNull(session, "AugmentedAutofillErrorCallback:")) {
+ return;
+ }
+ session.onAugmentedAutofillErrorCallback();
+ }
+ }
+
+ /**
+ * If the session is null or has been destroyed, log the error msg, and return true.
+ * This is a helper function intended to be called when de-referencing from a weak reference.
+ * @param session
+ * @param logPrefix
+ * @return true if the session is null, false otherwise.
+ */
+ private static boolean logIfSessionNull(Session session, String logPrefix) {
+ if (session == null) {
+ Slog.wtf(TAG, logPrefix + " Session null");
+ return true;
+ }
+ if (session.mDestroyed) {
+ // TODO: Update this to return in this block. We aren't doing this to preserve the
+ // behavior, but can be modified once we have more time to soak the changes.
+ Slog.w(TAG, logPrefix + " Session destroyed, but following through");
+ // Follow-through
+ }
+ return false;
+ }
+
+ private void onAugmentedAutofillInlineSuggestionAccept(
+ InlineSuggestionsRequest inlineSuggestionsRequest,
+ AutofillId focussedId,
+ boolean isAllowlisted,
+ int mode,
+ AutofillValue currentValue) {
+ synchronized (mLock) {
+ final RemoteAugmentedAutofillService remoteService =
+ mService.getRemoteAugmentedAutofillServiceLocked();
+ logAugmentedAutofillRequestLocked(mode, remoteService.getComponentName(),
+ focussedId, isAllowlisted, inlineSuggestionsRequest != null);
+ remoteService.onRequestAutofillLocked(id, mClient,
+ taskId, mComponentName, mActivityToken,
+ AutofillId.withoutSession(focussedId), currentValue,
+ inlineSuggestionsRequest,
+ new AugmentedAutofillInlineSuggestionsResponseCallback(this),
+ new AugmentedAutofillErrorCallback(this),
+ mService.getRemoteInlineSuggestionRenderServiceLocked(), userId);
+ }
+ }
+
+ private void onAugmentedAutofillErrorCallback() {
+ synchronized (mLock) {
+ cancelAugmentedAutofillLocked();
+
+ // Also cancel augmented in IME
+ mInlineSessionController.setInlineFillUiLocked(
+ InlineFillUi.emptyUi(mCurrentViewId));
+ }
+ }
+
@GuardedBy("mLock")
private void cancelAugmentedAutofillLocked() {
final RemoteAugmentedAutofillService remoteService = mService
@@ -5151,7 +5318,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
@NonNull
- private Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator(
+ Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator(
@NonNull Consumer<InlineSuggestionsRequest> consumer, int requestId) {
return inlineSuggestionsRequest -> {
consumer.accept(inlineSuggestionsRequest);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 6b99494f6564..a1ccade51214 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -1415,6 +1415,30 @@ public class CompanionDeviceManagerService extends SystemService {
mCrossDeviceSyncController.syncMessageToDevice(associationId, message);
}
}
+
+ @Override
+ public void sendCrossDeviceSyncMessageToAllDevices(int userId, byte[] message) {
+ if (CompanionDeviceConfig.isEnabled(
+ CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+ mCrossDeviceSyncController.syncMessageToAllDevicesForUserId(userId, message);
+ }
+ }
+
+ @Override
+ public void addSelfOwnedCallId(String callId) {
+ if (CompanionDeviceConfig.isEnabled(
+ CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+ mCrossDeviceSyncController.addSelfOwnedCallId(callId);
+ }
+ }
+
+ @Override
+ public void removeSelfOwnedCallId(String callId) {
+ if (CompanionDeviceConfig.isEnabled(
+ CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+ mCrossDeviceSyncController.removeSelfOwnedCallId(callId);
+ }
+ }
}
/**
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
index c5ef4e49e5ea..cdf832f8c788 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
@@ -45,6 +45,15 @@ public interface CompanionDeviceManagerServiceInternal {
*/
void sendCrossDeviceSyncMessage(int associationId, byte[] message);
+ /** Sends the provided message to all active associations for the specified user. */
+ void sendCrossDeviceSyncMessageToAllDevices(int userId, byte[] message);
+
+ /** Mark a call id as "self owned" (i.e. this device owns the canonical call). */
+ void addSelfOwnedCallId(String callId);
+
+ /** Unmark a call id as "self owned" (i.e. this device no longer owns the canonical call). */
+ void removeSelfOwnedCallId(String callId);
+
/**
* Requests a sync from an InCallService to CDM, for the given user and call metadata.
*/
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
index 7371824e9c9c..fac1c8981061 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
@@ -36,7 +36,7 @@ import com.android.server.companion.CompanionDeviceManagerServiceInternal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import java.util.UUID;
+import java.util.Set;
/** Service for Telecom to bind to when call metadata is synced between devices. */
public class CallMetadataSyncConnectionService extends ConnectionService {
@@ -65,11 +65,32 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
associationId, call.getId()));
if (existingConnection != null) {
existingConnection.update(call);
+ } else {
+ // Check if this is an in-progress id being finalized.
+ CallMetadataSyncConnectionIdentifier key = null;
+ for (Map.Entry<CallMetadataSyncConnectionIdentifier,
+ CallMetadataSyncConnection> e : mActiveConnections.entrySet()) {
+ if (e.getValue().getAssociationId() == associationId
+ && !e.getValue().isIdFinalized()
+ && call.getId().endsWith(e.getValue().getCallId())) {
+ key = e.getKey();
+ break;
+ }
+ }
+ if (key != null) {
+ final CallMetadataSyncConnection connection =
+ mActiveConnections.remove(key);
+ connection.update(call);
+ mActiveConnections.put(
+ new CallMetadataSyncConnectionIdentifier(associationId,
+ call.getId()), connection);
+ }
}
}
// Remove obsolete calls.
mActiveConnections.values().removeIf(connection -> {
- if (associationId == connection.getAssociationId()
+ if (connection.isIdFinalized()
+ && associationId == connection.getAssociationId()
&& !callMetadataSyncData.hasCall(connection.getCallId())) {
connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
return true;
@@ -77,6 +98,17 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
return false;
});
}
+
+ @Override
+ void cleanUpCallIds(Set<String> callIds) {
+ mActiveConnections.values().removeIf(connection -> {
+ if (callIds.contains(connection.getCallId())) {
+ connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+ return true;
+ }
+ return false;
+ });
+ }
};
@Override
@@ -95,10 +127,9 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
ConnectionRequest connectionRequest) {
final int associationId = connectionRequest.getExtras().getInt(
CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
- final CallMetadataSyncData.Call call = connectionRequest.getExtras().getParcelable(
- CrossDeviceSyncController.EXTRA_CALL, CallMetadataSyncData.Call.class);
- // InCallServices outside of framework (like Dialer's) might try to read this, and crash
- // when they can't. Remove it once we're done with it, as well as the other internal ones.
+ final CallMetadataSyncData.Call call = CallMetadataSyncData.Call.fromBundle(
+ connectionRequest.getExtras().getBundle(CrossDeviceSyncController.EXTRA_CALL));
+ call.setDirection(android.companion.Telecom.Call.INCOMING);
connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL);
connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID);
connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
@@ -130,18 +161,26 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle phoneAccountHandle,
ConnectionRequest connectionRequest) {
- final PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(phoneAccountHandle);
+ final PhoneAccountHandle handle = phoneAccountHandle != null ? phoneAccountHandle
+ : connectionRequest.getAccountHandle();
+ final PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(handle);
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
- call.setId(UUID.randomUUID().toString());
+ call.setId(
+ connectionRequest.getExtras().getString(CrossDeviceSyncController.EXTRA_CALL_ID));
call.setStatus(android.companion.Telecom.Call.UNKNOWN_STATUS);
final CallMetadataSyncData.CallFacilitator callFacilitator =
- new CallMetadataSyncData.CallFacilitator(phoneAccount.getLabel().toString(),
- phoneAccount.getExtras().getString(
- CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID));
+ new CallMetadataSyncData.CallFacilitator(phoneAccount != null
+ ? phoneAccount.getLabel().toString()
+ : handle.getComponentName().getShortClassName(),
+ phoneAccount != null ? phoneAccount.getExtras().getString(
+ CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID)
+ : handle.getComponentName().getPackageName());
call.setFacilitator(callFacilitator);
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setCallerId(connectionRequest.getAddress().getSchemeSpecificPart());
- final int associationId = connectionRequest.getExtras().getInt(
+ final int associationId = phoneAccount.getExtras().getInt(
CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL);
@@ -160,13 +199,15 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
CrossDeviceSyncController.createCallControlMessage(callId, action));
}
});
- connection.setConnectionProperties(Connection.PROPERTY_IS_EXTERNAL_CALL);
+ connection.setCallerDisplayName(call.getCallerId(), TelecomManager.PRESENTATION_ALLOWED);
+ mCdmsi.addSelfOwnedCallId(call.getId());
mCdmsi.sendCrossDeviceSyncMessage(associationId,
CrossDeviceSyncController.createCallCreateMessage(call.getId(),
connectionRequest.getAddress().toString(),
call.getFacilitator().getIdentifier()));
+ connection.setInitializing();
return connection;
}
@@ -240,6 +281,7 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
private final int mAssociationId;
private final CallMetadataSyncData.Call mCall;
private final CallMetadataSyncConnectionCallback mCallback;
+ private boolean mIsIdFinalized;
CallMetadataSyncConnection(TelecomManager telecomManager, AudioManager audioManager,
int associationId, CallMetadataSyncData.Call call,
@@ -259,6 +301,10 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
return mAssociationId;
}
+ public boolean isIdFinalized() {
+ return mIsIdFinalized;
+ }
+
private void initialize() {
final int status = mCall.getStatus();
if (status == android.companion.Telecom.Call.RINGING_SILENCED) {
@@ -273,6 +319,8 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
setOnHold();
} else if (state == Call.STATE_DISCONNECTED) {
setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+ } else if (state == Call.STATE_DIALING) {
+ setDialing();
} else {
setInitialized();
}
@@ -307,6 +355,10 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
}
private void update(CallMetadataSyncData.Call call) {
+ if (!mIsIdFinalized) {
+ mCall.setId(call.getId());
+ mIsIdFinalized = true;
+ }
final int status = call.getStatus();
if (status == android.companion.Telecom.Call.RINGING_SILENCED
&& mCall.getStatus() != android.companion.Telecom.Call.RINGING_SILENCED) {
@@ -323,6 +375,8 @@ public class CallMetadataSyncConnectionService extends ConnectionService {
setOnHold();
} else if (state == Call.STATE_DISCONNECTED) {
setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+ } else if (state == Call.STATE_DIALING) {
+ setDialing();
} else {
Slog.e(TAG, "Could not update call to unknown state");
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
index d8621cb796ab..74641a48c4dd 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
@@ -16,10 +16,8 @@
package com.android.server.companion.datatransfer.contextsync;
-import android.annotation.NonNull;
import android.companion.ContextSyncMessage;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.os.Bundle;
import java.util.ArrayList;
import java.util.Collection;
@@ -74,9 +72,10 @@ class CallMetadataSyncData {
return mCallFacilitators;
}
- public static class CallFacilitator implements Parcelable {
+ public static class CallFacilitator {
private String mName;
private String mIdentifier;
+ private boolean mIsTel;
CallFacilitator() {}
@@ -85,16 +84,6 @@ class CallMetadataSyncData {
mIdentifier = identifier;
}
- CallFacilitator(Parcel parcel) {
- this(parcel.readString(), parcel.readString());
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int parcelableFlags) {
- parcel.writeString(mName);
- parcel.writeString(mIdentifier);
- }
-
public String getName() {
return mName;
}
@@ -103,6 +92,10 @@ class CallMetadataSyncData {
return mIdentifier;
}
+ public boolean isTel() {
+ return mIsTel;
+ }
+
public void setName(String name) {
mName = name;
}
@@ -111,25 +104,9 @@ class CallMetadataSyncData {
mIdentifier = identifier;
}
- @Override
- public int describeContents() {
- return 0;
+ public void setIsTel(boolean isTel) {
+ mIsTel = isTel;
}
-
- @NonNull
- public static final Parcelable.Creator<CallFacilitator> CREATOR =
- new Parcelable.Creator<>() {
-
- @Override
- public CallFacilitator createFromParcel(Parcel source) {
- return new CallFacilitator(source);
- }
-
- @Override
- public CallFacilitator[] newArray(int size) {
- return new CallFacilitator[size];
- }
- };
}
public static class CallControlRequest {
@@ -183,40 +160,57 @@ class CallMetadataSyncData {
}
}
- public static class Call implements Parcelable {
+ public static class Call {
+
+ private static final String EXTRA_CALLER_ID =
+ "com.android.server.companion.datatransfer.contextsync.extra.CALLER_ID";
+ private static final String EXTRA_APP_ICON =
+ "com.android.server.companion.datatransfer.contextsync.extra.APP_ICON";
+ private static final String EXTRA_FACILITATOR_NAME =
+ "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_NAME";
+ private static final String EXTRA_FACILITATOR_ID =
+ "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_ID";
+ private static final String EXTRA_STATUS =
+ "com.android.server.companion.datatransfer.contextsync.extra.STATUS";
+ private static final String EXTRA_DIRECTION =
+ "com.android.server.companion.datatransfer.contextsync.extra.DIRECTION";
+ private static final String EXTRA_CONTROLS =
+ "com.android.server.companion.datatransfer.contextsync.extra.CONTROLS";
private String mId;
private String mCallerId;
private byte[] mAppIcon;
private CallFacilitator mFacilitator;
private int mStatus;
+ private int mDirection;
private final Set<Integer> mControls = new HashSet<>();
- public static Call fromParcel(Parcel parcel) {
+ public static Call fromBundle(Bundle bundle) {
final Call call = new Call();
- call.setId(parcel.readString());
- call.setCallerId(parcel.readString());
- call.setAppIcon(parcel.readBlob());
- call.setFacilitator(parcel.readParcelable(CallFacilitator.class.getClassLoader(),
- CallFacilitator.class));
- call.setStatus(parcel.readInt());
- final int numberOfControls = parcel.readInt();
- for (int i = 0; i < numberOfControls; i++) {
- call.addControl(parcel.readInt());
+ if (bundle != null) {
+ call.setId(bundle.getString(CrossDeviceSyncController.EXTRA_CALL_ID));
+ call.setCallerId(bundle.getString(EXTRA_CALLER_ID));
+ call.setAppIcon(bundle.getByteArray(EXTRA_APP_ICON));
+ final String facilitatorName = bundle.getString(EXTRA_FACILITATOR_NAME);
+ final String facilitatorIdentifier = bundle.getString(EXTRA_FACILITATOR_ID);
+ call.setFacilitator(new CallFacilitator(facilitatorName, facilitatorIdentifier));
+ call.setStatus(bundle.getInt(EXTRA_STATUS));
+ call.setDirection(bundle.getInt(EXTRA_DIRECTION));
+ call.setControls(new HashSet<>(bundle.getIntegerArrayList(EXTRA_CONTROLS)));
}
return call;
}
- @Override
- public void writeToParcel(Parcel parcel, int parcelableFlags) {
- parcel.writeString(mId);
- parcel.writeString(mCallerId);
- parcel.writeBlob(mAppIcon);
- parcel.writeParcelable(mFacilitator, parcelableFlags);
- parcel.writeInt(mStatus);
- parcel.writeInt(mControls.size());
- for (int control : mControls) {
- parcel.writeInt(control);
- }
+ public Bundle writeToBundle() {
+ final Bundle bundle = new Bundle();
+ bundle.putString(CrossDeviceSyncController.EXTRA_CALL_ID, mId);
+ bundle.putString(EXTRA_CALLER_ID, mCallerId);
+ bundle.putByteArray(EXTRA_APP_ICON, mAppIcon);
+ bundle.putString(EXTRA_FACILITATOR_NAME, mFacilitator.getName());
+ bundle.putString(EXTRA_FACILITATOR_ID, mFacilitator.getIdentifier());
+ bundle.putInt(EXTRA_STATUS, mStatus);
+ bundle.putInt(EXTRA_DIRECTION, mDirection);
+ bundle.putIntegerArrayList(EXTRA_CONTROLS, new ArrayList<>(mControls));
+ return bundle;
}
void setId(String id) {
@@ -239,6 +233,10 @@ class CallMetadataSyncData {
mStatus = status;
}
+ void setDirection(int direction) {
+ mDirection = direction;
+ }
+
void addControl(int control) {
mControls.add(control);
}
@@ -268,6 +266,10 @@ class CallMetadataSyncData {
return mStatus;
}
+ int getDirection() {
+ return mDirection;
+ }
+
Set<Integer> getControls() {
return mControls;
}
@@ -288,23 +290,5 @@ class CallMetadataSyncData {
public int hashCode() {
return Objects.hashCode(mId);
}
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull public static final Parcelable.Creator<Call> CREATOR = new Parcelable.Creator<>() {
-
- @Override
- public Call createFromParcel(Parcel source) {
- return Call.fromParcel(source);
- }
-
- @Override
- public Call[] newArray(int size) {
- return new Call[size];
- }
- };
}
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
index b46d5d3eab54..e6d36a543bf6 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
@@ -79,15 +79,20 @@ public class CallMetadataSyncInCallService extends InCallService {
int callControlAction) {
final CrossDeviceCall crossDeviceCall = getCallForId(crossDeviceCallId,
mCurrentCalls.values());
- if (crossDeviceCall == null) {
- return;
- }
switch (callControlAction) {
case android.companion.Telecom.ACCEPT:
- crossDeviceCall.doAccept();
+ if (crossDeviceCall != null) {
+ crossDeviceCall.doAccept();
+ } else {
+ Slog.w(TAG, "Failed to process accept action; no matching call");
+ }
break;
case android.companion.Telecom.REJECT:
- crossDeviceCall.doReject();
+ if (crossDeviceCall != null) {
+ crossDeviceCall.doReject();
+ } else {
+ Slog.w(TAG, "Failed to process reject action; no matching call");
+ }
break;
case android.companion.Telecom.SILENCE:
doSilence();
@@ -99,13 +104,25 @@ public class CallMetadataSyncInCallService extends InCallService {
doUnmute();
break;
case android.companion.Telecom.END:
- crossDeviceCall.doEnd();
+ if (crossDeviceCall != null) {
+ crossDeviceCall.doEnd();
+ } else {
+ Slog.w(TAG, "Failed to process end action; no matching call");
+ }
break;
case android.companion.Telecom.PUT_ON_HOLD:
- crossDeviceCall.doPutOnHold();
+ if (crossDeviceCall != null) {
+ crossDeviceCall.doPutOnHold();
+ } else {
+ Slog.w(TAG, "Failed to process hold action; no matching call");
+ }
break;
case android.companion.Telecom.TAKE_OFF_HOLD:
- crossDeviceCall.doTakeOffHold();
+ if (crossDeviceCall != null) {
+ crossDeviceCall.doTakeOffHold();
+ } else {
+ Slog.w(TAG, "Failed to process unhold action; no matching call");
+ }
break;
default:
}
@@ -188,6 +205,8 @@ public class CallMetadataSyncInCallService extends InCallService {
&& mNumberOfActiveSyncAssociations > 0) {
mCurrentCalls.remove(call);
call.unregisterCallback(mTelecomCallback);
+ mCdmsi.removeSelfOwnedCallId(call.getDetails().getExtras().getString(
+ CrossDeviceSyncController.EXTRA_CALL_ID));
sync(getUserId());
}
}
@@ -196,8 +215,9 @@ public class CallMetadataSyncInCallService extends InCallService {
public void onMuteStateChanged(boolean isMuted) {
if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
&& mNumberOfActiveSyncAssociations > 0) {
- mCurrentCalls.values().forEach(call -> call.updateMuted(isMuted));
- sync(getUserId());
+ mCdmsi.sendCrossDeviceSyncMessageToAllDevices(getUserId(),
+ CrossDeviceSyncController.createCallControlMessage(null, isMuted
+ ? android.companion.Telecom.MUTE : android.companion.Telecom.UNMUTE));
}
}
@@ -205,8 +225,9 @@ public class CallMetadataSyncInCallService extends InCallService {
public void onSilenceRinger() {
if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
&& mNumberOfActiveSyncAssociations > 0) {
- mCurrentCalls.values().forEach(call -> call.updateSilencedIfRinging());
- sync(getUserId());
+ mCdmsi.sendCrossDeviceSyncMessageToAllDevices(getUserId(),
+ CrossDeviceSyncController.createCallControlMessage(null,
+ android.companion.Telecom.SILENCE));
}
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
index fec6923e4d06..e8392d29365e 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
@@ -25,8 +25,10 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.telecom.Call;
import android.telecom.CallAudioState;
+import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
+import android.text.TextUtils;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -39,9 +41,11 @@ import java.util.UUID;
public class CrossDeviceCall {
private static final String TAG = "CrossDeviceCall";
+ private static final String SEPARATOR = "::";
private final String mId;
private final Call mCall;
+ private final int mUserId;
@VisibleForTesting boolean mIsEnterprise;
private final String mCallingAppPackageName;
private String mCallingAppName;
@@ -52,6 +56,7 @@ public class CrossDeviceCall {
private String mContactDisplayName;
private Uri mHandle;
private int mHandlePresentation;
+ private int mDirection;
private boolean mIsMuted;
private final Set<Integer> mControls = new HashSet<>();
private final boolean mIsCallPlacedByContextSync;
@@ -73,22 +78,24 @@ public class CrossDeviceCall {
? callDetails.getIntentExtras().getString(CrossDeviceSyncController.EXTRA_CALL_ID)
: null;
final String generatedId = UUID.randomUUID().toString();
- mId = predefinedId != null ? (generatedId + predefinedId) : generatedId;
+ mId = predefinedId != null ? (generatedId + SEPARATOR + predefinedId) : generatedId;
if (call != null) {
call.putExtra(CrossDeviceSyncController.EXTRA_CALL_ID, mId);
}
- mIsCallPlacedByContextSync =
- new ComponentName(context, CallMetadataSyncConnectionService.class)
- .equals(callDetails.getAccountHandle().getComponentName());
- mCallingAppPackageName =
- callDetails.getAccountHandle().getComponentName().getPackageName();
+ final PhoneAccountHandle handle = callDetails.getAccountHandle();
+ mUserId = handle != null ? handle.getUserHandle().getIdentifier() : -1;
+ mIsCallPlacedByContextSync = handle != null
+ && new ComponentName(context, CallMetadataSyncConnectionService.class)
+ .equals(handle.getComponentName());
+ mCallingAppPackageName = handle != null
+ ? callDetails.getAccountHandle().getComponentName().getPackageName() : "";
mIsEnterprise = (callDetails.getCallProperties() & Call.Details.PROPERTY_ENTERPRISE_CALL)
== Call.Details.PROPERTY_ENTERPRISE_CALL;
final PackageManager packageManager = context.getPackageManager();
try {
final ApplicationInfo applicationInfo = packageManager
- .getApplicationInfo(mCallingAppPackageName,
- PackageManager.ApplicationInfoFlags.of(0));
+ .getApplicationInfoAsUser(mCallingAppPackageName,
+ PackageManager.ApplicationInfoFlags.of(0), mUserId);
mCallingAppName = packageManager.getApplicationLabel(applicationInfo).toString();
mCallingAppIcon = BitmapUtils.renderDrawableToByteArray(
packageManager.getApplicationIcon(applicationInfo));
@@ -128,8 +135,19 @@ public class CrossDeviceCall {
mContactDisplayName = callDetails.getContactDisplayName();
mHandle = callDetails.getHandle();
mHandlePresentation = callDetails.getHandlePresentation();
+ final int direction = callDetails.getCallDirection();
+ if (direction == Call.Details.DIRECTION_INCOMING) {
+ mDirection = android.companion.Telecom.Call.INCOMING;
+ } else if (direction == Call.Details.DIRECTION_OUTGOING) {
+ mDirection = android.companion.Telecom.Call.OUTGOING;
+ } else {
+ mDirection = android.companion.Telecom.Call.UNKNOWN_DIRECTION;
+ }
mStatus = convertStateToStatus(callDetails.getState());
mControls.clear();
+ if (mStatus == android.companion.Telecom.Call.DIALING) {
+ mControls.add(android.companion.Telecom.END);
+ }
if (mStatus == android.companion.Telecom.Call.RINGING
|| mStatus == android.companion.Telecom.Call.RINGING_SILENCED) {
mControls.add(android.companion.Telecom.ACCEPT);
@@ -170,6 +188,8 @@ public class CrossDeviceCall {
return android.companion.Telecom.Call.RINGING_SIMULATED;
case Call.STATE_DISCONNECTED:
return android.companion.Telecom.Call.DISCONNECTED;
+ case Call.STATE_DIALING:
+ return android.companion.Telecom.Call.DIALING;
default:
Slog.e(TAG, "Couldn't resolve state to status: " + callState);
return android.companion.Telecom.Call.UNKNOWN_STATUS;
@@ -195,6 +215,8 @@ public class CrossDeviceCall {
return Call.STATE_SIMULATED_RINGING;
case android.companion.Telecom.Call.DISCONNECTED:
return Call.STATE_DISCONNECTED;
+ case android.companion.Telecom.Call.DIALING:
+ return Call.STATE_DIALING;
case android.companion.Telecom.Call.UNKNOWN_STATUS:
default:
return Call.STATE_NEW;
@@ -209,6 +231,10 @@ public class CrossDeviceCall {
return mCall;
}
+ public int getUserId() {
+ return mUserId;
+ }
+
public String getCallingAppName() {
return mCallingAppName;
}
@@ -231,11 +257,11 @@ public class CrossDeviceCall {
// Cannot use any contact information.
return getNonContactString();
}
- return mContactDisplayName != null ? mContactDisplayName : getNonContactString();
+ return TextUtils.isEmpty(mContactDisplayName) ? getNonContactString() : mContactDisplayName;
}
private String getNonContactString() {
- if (mCallerDisplayName != null
+ if (!TextUtils.isEmpty(mCallerDisplayName)
&& mCallerDisplayNamePresentation == TelecomManager.PRESENTATION_ALLOWED) {
return mCallerDisplayName;
}
@@ -250,6 +276,10 @@ public class CrossDeviceCall {
return mStatus;
}
+ public int getDirection() {
+ return mDirection;
+ }
+
public Set<Integer> getControls() {
return mControls;
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
index bf82f3f4a352..31694590a930 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
@@ -154,6 +154,7 @@ public class CrossDeviceSyncController {
Slog.w(TAG, "No callback to report removed transport");
}
}
+ clearInProgressCalls(associationInfo.getId());
} else {
// Stable association!
final boolean systemBlocked = isAssociationBlocked(associationInfo);
@@ -187,6 +188,7 @@ public class CrossDeviceSyncController {
// will get stale)
syncMessageToDevice(associationInfo.getId(),
createEmptyMessage());
+ clearInProgressCalls(associationInfo.getId());
}
}
}
@@ -201,9 +203,14 @@ public class CrossDeviceSyncController {
return;
}
final CallMetadataSyncData processedData = processTelecomDataFromSync(data);
- mPhoneAccountManager.updateFacilitators(associationId, processedData);
- mCallManager.updateCalls(associationId, processedData);
- processCallCreateRequests(processedData);
+ final boolean isRequest = processedData.getCallControlRequests().size() != 0
+ || processedData.getCallCreateRequests().size() != 0;
+ if (!isRequest) {
+ mPhoneAccountManager.updateFacilitators(associationId, processedData);
+ mCallManager.updateCalls(associationId, processedData);
+ } else {
+ processCallCreateRequests(processedData);
+ }
if (mInCallServiceCallbackRef == null
&& mConnectionServiceCallbackRef == null) {
Slog.w(TAG, "No callback to process context sync message");
@@ -213,8 +220,10 @@ public class CrossDeviceSyncController {
mInCallServiceCallbackRef != null ? mInCallServiceCallbackRef.get()
: null;
if (inCallServiceCallback != null) {
- inCallServiceCallback.processContextSyncMessage(associationId,
- processedData);
+ if (isRequest) {
+ inCallServiceCallback.processContextSyncMessage(associationId,
+ processedData);
+ }
} else {
// This is dead; get rid of it lazily
mInCallServiceCallbackRef = null;
@@ -224,8 +233,10 @@ public class CrossDeviceSyncController {
mConnectionServiceCallbackRef != null
? mConnectionServiceCallbackRef.get() : null;
if (connectionServiceCallback != null) {
- connectionServiceCallback.processContextSyncMessage(associationId,
- processedData);
+ if (!isRequest) {
+ connectionServiceCallback.processContextSyncMessage(associationId,
+ processedData);
+ }
} else {
// This is dead; get rid of it lazily
mConnectionServiceCallbackRef = null;
@@ -236,6 +247,15 @@ public class CrossDeviceSyncController {
mCallManager = new CallManager(mContext, mPhoneAccountManager);
}
+ private void clearInProgressCalls(int associationId) {
+ final Set<String> removedIds = mCallManager.clearCallIdsForAssociationId(associationId);
+ final CrossDeviceSyncControllerCallback connectionServiceCallback =
+ mConnectionServiceCallbackRef != null ? mConnectionServiceCallbackRef.get() : null;
+ if (connectionServiceCallback != null) {
+ connectionServiceCallback.cleanUpCallIds(removedIds);
+ }
+ }
+
private static boolean isAssociationBlocked(AssociationInfo info) {
return (info.getSystemDataSyncFlags() & CompanionDeviceManager.FLAG_CALL_METADATA)
!= CompanionDeviceManager.FLAG_CALL_METADATA;
@@ -274,6 +294,7 @@ public class CrossDeviceSyncController {
if (FACILITATOR_ID_SYSTEM.equals(request.getFacilitator().getIdentifier())) {
if (request.getAddress() != null && request.getAddress().startsWith(
PhoneAccount.SCHEME_TEL)) {
+ mCallManager.addSelfOwnedCallId(request.getId());
// Remove all the non-numbers (dashes, parens, scheme)
final Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL,
request.getAddress().replaceAll("\\D+", ""), /* fragment= */ null);
@@ -382,6 +403,38 @@ public class CrossDeviceSyncController {
new int[]{associationId});
}
+ /** Sync message to all associated devices. */
+ public void syncMessageToAllDevicesForUserId(int userId, byte[] message) {
+ final Set<Integer> associationIds = new HashSet<>();
+ for (AssociationInfo associationInfo : mConnectedAssociations) {
+ if (associationInfo.getUserId() == userId && !isAssociationBlocked(associationInfo)) {
+ associationIds.add(associationInfo.getId());
+ }
+ }
+ if (associationIds.isEmpty()) {
+ Slog.w(TAG, "No eligible devices to sync to");
+ return;
+ }
+
+ mCompanionTransportManager.sendMessage(MESSAGE_REQUEST_CONTEXT_SYNC, message,
+ associationIds.stream().mapToInt(Integer::intValue).toArray());
+ }
+
+ /**
+ * Mark a call id as owned (i.e. this device owns the canonical call). Note that both sides will
+ * own outgoing calls that were placed on behalf of another device.
+ */
+ public void addSelfOwnedCallId(String callId) {
+ mCallManager.addSelfOwnedCallId(callId);
+ }
+
+ /** Unmark a call id as owned (i.e. this device no longer owns the canonical call). */
+ public void removeSelfOwnedCallId(String callId) {
+ if (callId != null) {
+ mCallManager.removeSelfOwnedCallId(callId);
+ }
+ }
+
@VisibleForTesting
CallMetadataSyncData processTelecomDataFromSync(byte[] data) {
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
@@ -430,8 +483,10 @@ public class CrossDeviceSyncController {
pis.end(requestsToken);
} else if (pis.getFieldNumber() == (int) Telecom.FACILITATORS) {
final long facilitatorsToken = pis.start(Telecom.FACILITATORS);
- callMetadataSyncData.addFacilitator(
- processFacilitatorDataFromSync(pis));
+ final CallMetadataSyncData.CallFacilitator facilitator =
+ processFacilitatorDataFromSync(pis);
+ facilitator.setIsTel(true);
+ callMetadataSyncData.addFacilitator(facilitator);
pis.end(facilitatorsToken);
} else {
Slog.e(TAG, "Unhandled field in Telecom:"
@@ -561,6 +616,9 @@ public class CrossDeviceSyncController {
case (int) Telecom.Call.STATUS:
call.setStatus(pis.readInt(Telecom.Call.STATUS));
break;
+ case (int) Telecom.Call.DIRECTION:
+ call.setDirection(pis.readInt(Telecom.Call.DIRECTION));
+ break;
case (int) Telecom.Call.CONTROLS:
call.addControl(pis.readInt(Telecom.Call.CONTROLS));
break;
@@ -578,15 +636,15 @@ public class CrossDeviceSyncController {
pos.write(ContextSyncMessage.VERSION, CURRENT_VERSION);
final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
for (CrossDeviceCall call : calls) {
- if (call.isCallPlacedByContextSync()) {
- // Do not sync any calls which our "ours" as that would be duplicative.
+ if (call.isCallPlacedByContextSync() || mCallManager.isExternallyOwned(call.getId())) {
+ // Do not sync any of "our" calls, nor external calls, as that would be duplicative.
continue;
}
final long callsToken = pos.start(Telecom.CALLS);
pos.write(Telecom.Call.ID, call.getId());
final long originToken = pos.start(Telecom.Call.ORIGIN);
pos.write(Telecom.Call.Origin.CALLER_ID,
- call.getReadableCallerId(isAdminBlocked(userId)));
+ call.getReadableCallerId(isAdminBlocked(call.getUserId())));
pos.write(Telecom.Call.Origin.APP_ICON, call.getCallingAppIcon());
final long facilitatorToken = pos.start(Telecom.Call.Origin.FACILITATOR);
pos.write(Telecom.CallFacilitator.NAME, call.getCallingAppName());
@@ -594,6 +652,7 @@ public class CrossDeviceSyncController {
pos.end(facilitatorToken);
pos.end(originToken);
pos.write(Telecom.Call.STATUS, call.getStatus());
+ pos.write(Telecom.Call.DIRECTION, call.getDirection());
for (int control : call.getControls()) {
pos.write(Telecom.Call.CONTROLS, control);
}
@@ -658,6 +717,9 @@ public class CrossDeviceSyncController {
@VisibleForTesting
static class CallManager {
+ @VisibleForTesting final Set<String> mSelfOwnedCalls = new HashSet<>();
+ @VisibleForTesting final Set<String> mExternallyOwnedCalls = new HashSet<>();
+
@VisibleForTesting final Map<Integer, Set<String>> mCallIds = new HashMap<>();
private final TelecomManager mTelecomManager;
private final PhoneAccountManager mPhoneAccountManager;
@@ -678,20 +740,63 @@ public class CrossDeviceSyncController {
for (CallMetadataSyncData.Call currentCall : data.getCalls()) {
if (!oldCallIds.contains(currentCall.getId())
- && currentCall.getFacilitator() != null) {
+ && currentCall.getFacilitator() != null
+ && !isSelfOwned(currentCall.getId())) {
+ mExternallyOwnedCalls.add(currentCall.getId());
final Bundle extras = new Bundle();
extras.putInt(EXTRA_ASSOCIATION_ID, associationId);
extras.putBoolean(EXTRA_IS_REMOTE_ORIGIN, true);
- extras.putParcelable(EXTRA_CALL, currentCall);
+ extras.putBundle(EXTRA_CALL, currentCall.writeToBundle());
extras.putString(EXTRA_CALL_ID, currentCall.getId());
extras.putByteArray(EXTRA_FACILITATOR_ICON, currentCall.getAppIcon());
- final PhoneAccountHandle handle = mPhoneAccountManager.getPhoneAccountHandle(
- associationId, currentCall.getFacilitator().getIdentifier());
- mTelecomManager.addNewIncomingCall(handle, extras);
+ final PhoneAccountHandle handle =
+ mPhoneAccountManager.getPhoneAccountHandle(
+ associationId,
+ currentCall.getFacilitator().getIdentifier());
+ if (currentCall.getDirection() == android.companion.Telecom.Call.INCOMING) {
+ mTelecomManager.addNewIncomingCall(handle, extras);
+ } else if (currentCall.getDirection()
+ == android.companion.Telecom.Call.OUTGOING) {
+ final Bundle wrappedExtras = new Bundle();
+ wrappedExtras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,
+ extras);
+ wrappedExtras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+ handle);
+ final String address = currentCall.getCallerId();
+ if (address != null) {
+ mTelecomManager.placeCall(Uri.fromParts(PhoneAccount.SCHEME_SIP,
+ address, /* fragment= */ null), wrappedExtras);
+ }
+ }
}
}
mCallIds.put(associationId, newCallIds);
}
+
+ Set<String> clearCallIdsForAssociationId(int associationId) {
+ return mCallIds.remove(associationId);
+ }
+
+ void addSelfOwnedCallId(String callId) {
+ mSelfOwnedCalls.add(callId);
+ }
+
+ void removeSelfOwnedCallId(String callId) {
+ mSelfOwnedCalls.remove(callId);
+ }
+
+ boolean isExternallyOwned(String callId) {
+ return mExternallyOwnedCalls.contains(callId);
+ }
+
+ private boolean isSelfOwned(String currentCallId) {
+ for (String selfOwnedCallId : mSelfOwnedCalls) {
+ if (currentCallId.endsWith(selfOwnedCallId)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
static class PhoneAccountManager {
@@ -745,7 +850,8 @@ public class CrossDeviceSyncController {
new PhoneAccountHandleIdentifier(associationId,
facilitator.getIdentifier());
if (!mPhoneAccountHandles.containsKey(phoneAccountHandleIdentifier)) {
- registerPhoneAccount(phoneAccountHandleIdentifier, facilitator.getName());
+ registerPhoneAccount(phoneAccountHandleIdentifier, facilitator.getName(),
+ facilitator.isTel());
}
}
}
@@ -755,7 +861,7 @@ public class CrossDeviceSyncController {
* synced device, and records it in the local {@link #mPhoneAccountHandles} map.
*/
private void registerPhoneAccount(PhoneAccountHandleIdentifier handleIdentifier,
- String humanReadableAppName) {
+ String humanReadableAppName, boolean isTel) {
if (mPhoneAccountHandles.containsKey(handleIdentifier)) {
// Already exists!
return;
@@ -765,7 +871,8 @@ public class CrossDeviceSyncController {
UUID.randomUUID().toString());
mPhoneAccountHandles.put(handleIdentifier, handle);
final PhoneAccount phoneAccount = createPhoneAccount(handle, humanReadableAppName,
- handleIdentifier.getAppIdentifier());
+ handleIdentifier.getAppIdentifier(), handleIdentifier.getAssociationId(),
+ isTel);
mTelecomManager.registerPhoneAccount(phoneAccount);
mTelecomManager.enablePhoneAccount(mPhoneAccountHandles.get(handleIdentifier), true);
}
@@ -781,11 +888,16 @@ public class CrossDeviceSyncController {
@VisibleForTesting
static PhoneAccount createPhoneAccount(PhoneAccountHandle handle,
String humanReadableAppName,
- String appIdentifier) {
+ String appIdentifier,
+ int associationId,
+ boolean isTel) {
final Bundle extras = new Bundle();
extras.putString(EXTRA_CALL_FACILITATOR_ID, appIdentifier);
+ extras.putInt(EXTRA_ASSOCIATION_ID, associationId);
return new PhoneAccount.Builder(handle, humanReadableAppName)
.setExtras(extras)
+ .setSupportedUriSchemes(List.of(isTel ? PhoneAccount.SCHEME_TEL
+ : PhoneAccount.SCHEME_SIP))
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
| PhoneAccount.CAPABILITY_CONNECTION_MANAGER).build();
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
index 8a0ba27b7526..6764830b830b 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
@@ -21,6 +21,7 @@ import android.companion.AssociationInfo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
/** Callback for call metadata syncing. */
public abstract class CrossDeviceSyncControllerCallback {
@@ -40,4 +41,7 @@ public abstract class CrossDeviceSyncControllerCallback {
void requestCrossDeviceSync(AssociationInfo associationInfo) {}
void updateNumberOfActiveSyncAssociations(int userId, boolean added) {}
+
+ /** Clean up any remaining state for the given calls. */
+ void cleanUpCallIds(Set<String> callIds) {}
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 61fc32d5fa15..51359add8fd1 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -163,13 +163,35 @@ public final class ContentCaptureManagerService extends
private boolean mDisabledByDeviceConfig;
// Device-config settings that are cached and passed back to apps
- @GuardedBy("mLock") int mDevCfgLoggingLevel;
- @GuardedBy("mLock") int mDevCfgMaxBufferSize;
- @GuardedBy("mLock") int mDevCfgIdleFlushingFrequencyMs;
- @GuardedBy("mLock") int mDevCfgTextChangeFlushingFrequencyMs;
- @GuardedBy("mLock") int mDevCfgLogHistorySize;
- @GuardedBy("mLock") int mDevCfgIdleUnbindTimeoutMs;
- @GuardedBy("mLock") boolean mDevCfgDisableFlushForViewTreeAppearing;
+ @GuardedBy("mLock")
+ int mDevCfgLoggingLevel;
+
+ @GuardedBy("mLock")
+ int mDevCfgMaxBufferSize;
+
+ @GuardedBy("mLock")
+ int mDevCfgIdleFlushingFrequencyMs;
+
+ @GuardedBy("mLock")
+ int mDevCfgTextChangeFlushingFrequencyMs;
+
+ @GuardedBy("mLock")
+ int mDevCfgLogHistorySize;
+
+ @GuardedBy("mLock")
+ int mDevCfgIdleUnbindTimeoutMs;
+
+ @GuardedBy("mLock")
+ boolean mDevCfgDisableFlushForViewTreeAppearing;
+
+ @GuardedBy("mLock")
+ boolean mDevCfgEnableContentProtectionReceiver;
+
+ @GuardedBy("mLock")
+ int mDevCfgContentProtectionAppsBlocklistSize;
+
+ @GuardedBy("mLock")
+ int mDevCfgContentProtectionBufferSize;
private final Executor mDataShareExecutor = Executors.newCachedThreadPool();
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -362,6 +384,11 @@ public final class ContentCaptureManagerService extends
case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT:
case ContentCaptureManager
.DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING:
+ case ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER:
+ case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE:
+ case ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE:
setFineTuneParamsFromDeviceConfig();
return;
default:
@@ -372,39 +399,78 @@ public final class ContentCaptureManagerService extends
private void setFineTuneParamsFromDeviceConfig() {
synchronized (mLock) {
- mDevCfgMaxBufferSize = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE,
- ContentCaptureManager.DEFAULT_MAX_BUFFER_SIZE);
- mDevCfgIdleFlushingFrequencyMs = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY,
- ContentCaptureManager.DEFAULT_IDLE_FLUSHING_FREQUENCY_MS);
- mDevCfgTextChangeFlushingFrequencyMs = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY,
- ContentCaptureManager.DEFAULT_TEXT_CHANGE_FLUSHING_FREQUENCY_MS);
- mDevCfgLogHistorySize = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE, 20);
- mDevCfgIdleUnbindTimeoutMs = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT,
- (int) AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS);
- mDevCfgDisableFlushForViewTreeAppearing = DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager
- .DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING,
- false);
+ mDevCfgMaxBufferSize =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE,
+ ContentCaptureManager.DEFAULT_MAX_BUFFER_SIZE);
+ mDevCfgIdleFlushingFrequencyMs =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY,
+ ContentCaptureManager.DEFAULT_IDLE_FLUSHING_FREQUENCY_MS);
+ mDevCfgTextChangeFlushingFrequencyMs =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY,
+ ContentCaptureManager.DEFAULT_TEXT_CHANGE_FLUSHING_FREQUENCY_MS);
+ mDevCfgLogHistorySize =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE,
+ 20);
+ mDevCfgIdleUnbindTimeoutMs =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT,
+ (int) AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS);
+ mDevCfgDisableFlushForViewTreeAppearing =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING,
+ false);
+ mDevCfgEnableContentProtectionReceiver =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
+ ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER);
+ mDevCfgContentProtectionAppsBlocklistSize =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE,
+ ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE);
+ mDevCfgContentProtectionBufferSize =
+ DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager
+ .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE,
+ ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE);
if (verbose) {
- Slog.v(TAG, "setFineTuneParamsFromDeviceConfig(): "
- + "bufferSize=" + mDevCfgMaxBufferSize
- + ", idleFlush=" + mDevCfgIdleFlushingFrequencyMs
- + ", textFluxh=" + mDevCfgTextChangeFlushingFrequencyMs
- + ", logHistory=" + mDevCfgLogHistorySize
- + ", idleUnbindTimeoutMs=" + mDevCfgIdleUnbindTimeoutMs
- + ", disableFlushForViewTreeAppearing="
- + mDevCfgDisableFlushForViewTreeAppearing);
+ Slog.v(
+ TAG,
+ "setFineTuneParamsFromDeviceConfig(): "
+ + "bufferSize="
+ + mDevCfgMaxBufferSize
+ + ", idleFlush="
+ + mDevCfgIdleFlushingFrequencyMs
+ + ", textFluxh="
+ + mDevCfgTextChangeFlushingFrequencyMs
+ + ", logHistory="
+ + mDevCfgLogHistorySize
+ + ", idleUnbindTimeoutMs="
+ + mDevCfgIdleUnbindTimeoutMs
+ + ", disableFlushForViewTreeAppearing="
+ + mDevCfgDisableFlushForViewTreeAppearing
+ + ", enableContentProtectionReceiver="
+ + mDevCfgEnableContentProtectionReceiver
+ + ", contentProtectionAppsBlocklistSize="
+ + mDevCfgContentProtectionAppsBlocklistSize
+ + ", contentProtectionBufferSize="
+ + mDevCfgContentProtectionBufferSize);
}
}
}
@@ -645,21 +711,46 @@ public final class ContentCaptureManagerService extends
final String prefix2 = prefix + " ";
- pw.print(prefix); pw.print("Users disabled by Settings: "); pw.println(mDisabledBySettings);
- pw.print(prefix); pw.println("DeviceConfig Settings: ");
- pw.print(prefix2); pw.print("disabled: "); pw.println(mDisabledByDeviceConfig);
- pw.print(prefix2); pw.print("loggingLevel: "); pw.println(mDevCfgLoggingLevel);
- pw.print(prefix2); pw.print("maxBufferSize: "); pw.println(mDevCfgMaxBufferSize);
- pw.print(prefix2); pw.print("idleFlushingFrequencyMs: ");
+ pw.print(prefix);
+ pw.print("Users disabled by Settings: ");
+ pw.println(mDisabledBySettings);
+ pw.print(prefix);
+ pw.println("DeviceConfig Settings: ");
+ pw.print(prefix2);
+ pw.print("disabled: ");
+ pw.println(mDisabledByDeviceConfig);
+ pw.print(prefix2);
+ pw.print("loggingLevel: ");
+ pw.println(mDevCfgLoggingLevel);
+ pw.print(prefix2);
+ pw.print("maxBufferSize: ");
+ pw.println(mDevCfgMaxBufferSize);
+ pw.print(prefix2);
+ pw.print("idleFlushingFrequencyMs: ");
pw.println(mDevCfgIdleFlushingFrequencyMs);
- pw.print(prefix2); pw.print("textChangeFlushingFrequencyMs: ");
+ pw.print(prefix2);
+ pw.print("textChangeFlushingFrequencyMs: ");
pw.println(mDevCfgTextChangeFlushingFrequencyMs);
- pw.print(prefix2); pw.print("logHistorySize: "); pw.println(mDevCfgLogHistorySize);
- pw.print(prefix2); pw.print("idleUnbindTimeoutMs: ");
+ pw.print(prefix2);
+ pw.print("logHistorySize: ");
+ pw.println(mDevCfgLogHistorySize);
+ pw.print(prefix2);
+ pw.print("idleUnbindTimeoutMs: ");
pw.println(mDevCfgIdleUnbindTimeoutMs);
- pw.print(prefix2); pw.print("disableFlushForViewTreeAppearing: ");
+ pw.print(prefix2);
+ pw.print("disableFlushForViewTreeAppearing: ");
pw.println(mDevCfgDisableFlushForViewTreeAppearing);
- pw.print(prefix); pw.println("Global Options:");
+ pw.print(prefix2);
+ pw.print("enableContentProtectionReceiver: ");
+ pw.println(mDevCfgEnableContentProtectionReceiver);
+ pw.print(prefix2);
+ pw.print("contentProtectionAppsBlocklistSize: ");
+ pw.println(mDevCfgContentProtectionAppsBlocklistSize);
+ pw.print(prefix2);
+ pw.print("contentProtectionBufferSize: ");
+ pw.println(mDevCfgContentProtectionBufferSize);
+ pw.print(prefix);
+ pw.println("Global Options:");
mGlobalContentCaptureOptions.dump(prefix2, pw);
}
@@ -1019,11 +1110,19 @@ public final class ContentCaptureManagerService extends
}
synchronized (mLock) {
- final ContentCaptureOptions options = new ContentCaptureOptions(mDevCfgLoggingLevel,
- mDevCfgMaxBufferSize, mDevCfgIdleFlushingFrequencyMs,
- mDevCfgTextChangeFlushingFrequencyMs, mDevCfgLogHistorySize,
- mDevCfgDisableFlushForViewTreeAppearing,
- whitelistedComponents);
+ final ContentCaptureOptions options =
+ new ContentCaptureOptions(
+ mDevCfgLoggingLevel,
+ mDevCfgMaxBufferSize,
+ mDevCfgIdleFlushingFrequencyMs,
+ mDevCfgTextChangeFlushingFrequencyMs,
+ mDevCfgLogHistorySize,
+ mDevCfgDisableFlushForViewTreeAppearing,
+ /* enableReceiver= */ true,
+ new ContentCaptureOptions.ContentProtectionOptions(
+ mDevCfgEnableContentProtectionReceiver,
+ mDevCfgContentProtectionBufferSize),
+ whitelistedComponents);
if (verbose) Slog.v(TAG, "getOptionsForPackage(" + packageName + "): " + options);
return options;
}
diff --git a/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java b/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java
new file mode 100644
index 000000000000..7b34e737b58c
--- /dev/null
+++ b/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.contentprotection;
+
+import static android.view.contentcapture.ContentCaptureSession.FLUSH_REASON_LOGIN_DETECTED;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.service.contentcapture.ContentCaptureService;
+import android.util.Slog;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.IContentCaptureDirectManager;
+
+import com.android.internal.infra.ServiceConnector;
+
+import java.time.Duration;
+
+/**
+ * Connector for the remote content protection service.
+ *
+ * @hide
+ */
+class RemoteContentProtectionService extends ServiceConnector.Impl<IContentCaptureDirectManager> {
+
+ private static final String TAG = RemoteContentProtectionService.class.getSimpleName();
+
+ private static final Duration AUTO_DISCONNECT_TIMEOUT = Duration.ofSeconds(3);
+
+ @NonNull private final ComponentName mComponentName;
+
+ protected RemoteContentProtectionService(
+ @NonNull Context context,
+ @NonNull ComponentName componentName,
+ int userId,
+ boolean bindAllowInstant) {
+ super(
+ context,
+ new Intent(ContentCaptureService.PROTECTION_SERVICE_INTERFACE)
+ .setComponent(componentName),
+ bindAllowInstant ? Context.BIND_ALLOW_INSTANT : 0,
+ userId,
+ IContentCaptureDirectManager.Stub::asInterface);
+ mComponentName = componentName;
+ }
+
+ @Override // from ServiceConnector.Impl
+ protected long getAutoDisconnectTimeoutMs() {
+ return AUTO_DISCONNECT_TIMEOUT.toMillis();
+ }
+
+ @Override // from ServiceConnector.Impl
+ protected void onServiceConnectionStatusChanged(
+ @NonNull IContentCaptureDirectManager service, boolean isConnected) {
+ Slog.i(
+ TAG,
+ "Connection status for: "
+ + mComponentName
+ + " changed to: "
+ + (isConnected ? "connected" : "disconnected"));
+ }
+
+ public void onLoginDetected(@NonNull ParceledListSlice<ContentCaptureEvent> events) {
+ run(
+ service ->
+ service.sendEvents(
+ events, FLUSH_REASON_LOGIN_DETECTED, /* options= */ null));
+ }
+}
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 2b43ef48b922..9b4f9683d550 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -406,7 +406,7 @@ public class VpnManagerService extends IVpnManager.Stub {
* Retrieve the VpnProfileState for the profile provisioned by the given package.
*
* @return the VpnProfileState with current information, or null if there was no profile
- * provisioned by the given package.
+ * provisioned and started by the given package.
* @hide
*/
@Override
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 31d60f25ef24..6db8ea7e536e 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2156,7 +2156,6 @@ public final class ActiveServices {
}
}
- final boolean enableFgsWhileInUseFix = mAm.mConstants.mEnableFgsWhileInUseFix;
final boolean fgsTypeChangingFromShortFgs = r.isForeground && isOldTypeShortFgs;
if (fgsTypeChangingFromShortFgs) {
@@ -2214,19 +2213,7 @@ public final class ActiveServices {
}
}
- boolean resetNeededForLogging = false;
-
- // Re-evaluate mAllowWhileInUsePermissionInFgs and mAllowStartForeground
- // (i.e. while-in-use and BFSL flags) if needed.
- //
- // Consider the below if-else section to be in the else of the above
- // `if (fgsTypeChangingFromShortFgs)`.
- // Using an else would increase the indent further, so we don't use it here
- // and instead just add !fgsTypeChangingFromShortFgs to all if's.
- //
- // The first if's are for the original while-in-use logic.
- if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
- && r.mStartForegroundCount == 0) {
+ if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount == 0) {
/*
If the service was started with startService(), not
startForegroundService(), and if startForeground() isn't called within
@@ -2257,8 +2244,7 @@ public final class ActiveServices {
r.mLoggedInfoAllowStartForeground = false;
}
}
- } else if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
- && r.mStartForegroundCount >= 1) {
+ } else if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount >= 1) {
// We get here if startForeground() is called multiple times
// on the same service after it's created, regardless of whether
// stopForeground() has been called or not.
@@ -2269,100 +2255,6 @@ public final class ActiveServices {
r.appInfo.uid, r.intent.getIntent(), r, r.userId,
BackgroundStartPrivileges.NONE,
false /* isBindService */, false /* isStartService */);
- } else if (!fgsTypeChangingFromShortFgs && enableFgsWhileInUseFix) {
- // The new while-in-use logic.
- //
- // When startForeground() is called, we _always_ call
- // setFgsRestrictionLocked() to set the restrictions according to the
- // current state of the app.
- // (So if the app is now in TOP, for example, the service will now always
- // get while-in-use permissions.)
- //
- // Note, setFgsRestrictionLocked() will never disallow
- // mAllowWhileInUsePermissionInFgs nor mAllowStartForeground
- // (i.e. while-in-use and BFSL flags) once they're set to "allowed".
- //
- // HOWEVER, if these flags were set to "allowed" in Context.startService()
- // (as opposed to startForegroundService()), when the service wasn't yet
- // a foreground service, then we may not always
- // want to trust them -- for example, if the service has been running as a
- // BG service or a bound service for a long time when the app is not longer
- // in the foreground, then we shouldn't grant while-in-user nor BFSL.
- // So in that case, we need to reset it first.
-
- final long delayMs =
- (r.mLastUntrustedSetFgsRestrictionAllowedTime == 0) ? 0
- : (SystemClock.elapsedRealtime()
- - r.mLastUntrustedSetFgsRestrictionAllowedTime);
- final boolean resetNeeded =
- !r.isForeground
- && delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs;
- if (resetNeeded) {
- // We don't want to reset mDebugWhileInUseReasonInBindService here --
- // we'll instead reset it in the following code, using the simulated
- // legacy logic.
- resetFgsRestrictionLocked(r,
- /*resetDebugWhileInUseReasonInBindService=*/ false);
- }
-
- // Simulate the reset flow in the legacy logic to reset
- // mDebugWhileInUseReasonInBindService.
- // (Which is only used to compare to the old logic.)
- final long legacyDelayMs = SystemClock.elapsedRealtime() - r.createRealTime;
- if ((r.mStartForegroundCount == 0)
- && (legacyDelayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs)) {
- r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
- }
-
- setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
- r.appInfo.uid, r.intent.getIntent(), r, r.userId,
- BackgroundStartPrivileges.NONE,
- false /* isBindService */, false /* isStartService */);
-
- final String temp = "startForegroundDelayMs:" + delayMs
- + "; started: " + r.startRequested
- + "; num_bindings: " + r.getConnections().size()
- + "; wasForeground: " + r.isForeground
- + "; resetNeeded:" + resetNeeded;
- if (r.mInfoAllowStartForeground != null) {
- r.mInfoAllowStartForeground += "; " + temp;
- } else {
- r.mInfoAllowStartForeground = temp;
- }
- r.mLoggedInfoAllowStartForeground = false;
-
- resetNeededForLogging = resetNeeded;
- }
-
- // If the service has any bindings and it's not yet a FGS
- // we compare the new and old while-in-use logics.
- // (If it's not the first startForeground() call, we already reset the
- // while-in-use and BFSL flags, so the logic change wouldn't matter.)
- //
- // Note, mDebugWhileInUseReasonInBindService does *not* fully simulate the
- // legacy logic, because we'll only set it in bindService(), but the actual
- // mAllowWhileInUsePermissionInFgsReason can change afterwards, in a subsequent
- // Service.startForeground(). This check will only provide "rough" check.
- // But if mDebugWhileInUseReasonInBindService is _not_ DENIED, and
- // mDebugWhileInUseReasonInStartForeground _is_ DENIED, then that means we'd
- // now detected a behavior change.
- // OTOH, if it's changing from non-DENIED to another non-DENIED, that may
- // not be a problem.
- if (enableFgsWhileInUseFix
- && !r.isForeground
- && (r.getConnections().size() > 0)
- && (r.mDebugWhileInUseReasonInBindService
- != r.mDebugWhileInUseReasonInStartForeground)) {
- logWhileInUseChangeWtf("FGS while-in-use changed (b/276963716): old="
- + reasonCodeToString(r.mDebugWhileInUseReasonInBindService)
- + " new="
- + reasonCodeToString(r.mDebugWhileInUseReasonInStartForeground)
- + " startForegroundCount=" + r.mStartForegroundCount
- + " started=" + r.startRequested
- + " num_bindings=" + r.getConnections().size()
- + " resetNeeded=" + resetNeededForLogging
- + " "
- + r.shortInstanceName);
}
// If the foreground service is not started from TOP process, do not allow it to
@@ -2471,10 +2363,6 @@ public final class ActiveServices {
}
r.isForeground = true;
- // Once the service becomes a foreground service,
- // the FGS restriction information always becomes "trustable".
- r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
-
// The logging of FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER event could
// be deferred, make a copy of mAllowStartForeground and
// mAllowWhileInUsePermissionInFgs.
@@ -2620,13 +2508,6 @@ public final class ActiveServices {
}
}
- /**
- * It just does a wtf, but extracted to a method, so we can do a signature search on pitot.
- */
- private void logWhileInUseChangeWtf(String message) {
- Slog.wtf(TAG, message);
- }
-
private boolean withinFgsDeferRateLimit(ServiceRecord sr, final long now) {
// If we're still within the service's deferral period, then by definition
// deferral is not rate limited.
@@ -3797,7 +3678,9 @@ public final class ActiveServices {
}
clientPsr.addConnection(c);
c.startAssociationIfNeeded();
- if (c.hasFlag(Context.BIND_ABOVE_CLIENT)) {
+ // Don't set hasAboveClient if binding to self to prevent modifyRawOomAdj() from
+ // dropping the process' adjustment level.
+ if (b.client != s.app && c.hasFlag(Context.BIND_ABOVE_CLIENT)) {
clientPsr.setHasAboveClient(true);
}
if (c.hasFlag(BIND_ALLOW_WHITELIST_MANAGEMENT)) {
@@ -3837,25 +3720,9 @@ public final class ActiveServices {
return 0;
}
}
- if (!mAm.mConstants.mEnableFgsWhileInUseFix) {
- // Old while-in-use logic.
- setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
- BackgroundStartPrivileges.NONE, true /* isBindService */,
- false /* isStartService */);
- } else {
- // New logic will not call setFgsRestrictionLocked() here, but we still
- // keep track of the allow reason from the old logic here, so we can compare to
- // the new logic.
- // Once we're confident enough in the new logic, we should remove it.
- if (s.mDebugWhileInUseReasonInBindService == REASON_DENIED) {
- s.mDebugWhileInUseReasonInBindService =
- shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, s.app,
- BackgroundStartPrivileges.NONE,
- true /* isBindService */,
- false /* DO NOT enableFgsWhileInUseFix; use the old logic */);
- }
- }
+ setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
+ BackgroundStartPrivileges.NONE, true /* isBindService */,
+ false /* isStartService */);
if (s.app != null) {
ProcessServiceRecord servicePsr = s.app.mServices;
@@ -7552,15 +7419,13 @@ public final class ActiveServices {
* @param r the service to start.
* @param isStartService True if it's called from Context.startService().
* False if it's called from Context.startForegroundService() or
- * Service.startService().
+ * Service.startForeground().
* @return true if allow, false otherwise.
*/
private void setFgsRestrictionLocked(String callingPackage,
int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
boolean isStartService) {
- final long now = SystemClock.elapsedRealtime();
-
// Check DeviceConfig flag.
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
r.mAllowWhileInUsePermissionInFgs = true;
@@ -7578,60 +7443,30 @@ public final class ActiveServices {
isBindService);
// We store them to compare the old and new while-in-use logics to each other.
// (They're not used for any other purposes.)
- if (isBindService) {
- r.mDebugWhileInUseReasonInBindService = allowWhileInUse;
- } else {
- r.mDebugWhileInUseReasonInStartForeground = allowWhileInUse;
- }
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
- newlyAllowed |= r.mAllowWhileInUsePermissionInFgs;
}
if (r.mAllowStartForeground == REASON_DENIED) {
r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
backgroundStartPrivileges, isBindService);
- newlyAllowed |= r.mAllowStartForeground != REASON_DENIED;
}
} else {
allowWhileInUse = REASON_UNKNOWN;
}
r.mAllowWhileInUsePermissionInFgsReason = allowWhileInUse;
-
- if (isStartService && !r.isForeground && newlyAllowed) {
- // If it's called by Context.startService() (not by startForegroundService()),
- // and we're setting "allowed", then we can't fully trust it yet -- we'll need to reset
- // the restrictions if startForeground() is called after the grace period.
- r.mLastUntrustedSetFgsRestrictionAllowedTime = now;
- }
}
/**
* Reset various while-in-use and BFSL related information.
*/
void resetFgsRestrictionLocked(ServiceRecord r) {
- resetFgsRestrictionLocked(r, /*resetDebugWhileInUseReasonInBindService=*/ true);
- }
-
- /**
- * Reset various while-in-use and BFSL related information.
- */
- void resetFgsRestrictionLocked(ServiceRecord r,
- boolean resetDebugWhileInUseReasonInBindService) {
r.mAllowWhileInUsePermissionInFgs = false;
r.mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
- r.mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
-
- // In Service.startForeground(), we reset this field using a legacy logic,
- // so resetting this field is optional.
- if (resetDebugWhileInUseReasonInBindService) {
- r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
- }
r.mAllowStartForeground = REASON_DENIED;
r.mInfoAllowStartForeground = null;
r.mInfoTempFgsAllowListReason = null;
r.mLoggedInfoAllowStartForeground = false;
- r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
r.updateAllowUiJobScheduling(r.mAllowWhileInUsePermissionInFgs);
}
@@ -7666,22 +7501,11 @@ public final class ActiveServices {
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService) {
- return shouldAllowFgsWhileInUsePermissionLocked(callingPackage,
- callingPid, callingUid, targetProcess, backgroundStartPrivileges, isBindService,
- /* enableFgsWhileInUseFix =*/ mAm.mConstants.mEnableFgsWhileInUseFix);
- }
-
- private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
- int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
- BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
- boolean enableFgsWhileInUseFix) {
int ret = REASON_DENIED;
- // Define some local variables for better readability...
- final boolean useOldLogic = !enableFgsWhileInUseFix;
final boolean forStartForeground = !isBindService;
- if (useOldLogic || forStartForeground) {
+ if (forStartForeground) {
final int uidState = mAm.getUidStateLocked(callingUid);
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the caller's process state is PROCESS_STATE_PERSISTENT,
@@ -7731,10 +7555,6 @@ public final class ActiveServices {
}
}
- if (enableFgsWhileInUseFix && ret == REASON_DENIED) {
- ret = shouldAllowFgsWhileInUsePermissionByBindingsLocked(callingUid);
- }
-
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the WindowManager allows background activity start.
// This is mainly to get the 10 seconds grace period if any activity in the caller has
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 3b446338298d..44e198b53761 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -1058,13 +1058,6 @@ final class ActivityManagerConstants extends ContentObserver {
/** @see #KEY_USE_MODERN_TRIM */
public boolean USE_MODERN_TRIM = DEFAULT_USE_MODERN_TRIM;
- private static final String KEY_ENABLE_FGS_WHILE_IN_USE_FIX =
- "key_enable_fgs_while_in_use_fix";
-
- private static final boolean DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX = false;
-
- public volatile boolean mEnableFgsWhileInUseFix = DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX;
-
private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
new OnPropertiesChangedListener() {
@Override
@@ -1233,9 +1226,6 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION:
updateEnableWaitForFinishAttachApplication();
break;
- case KEY_ENABLE_FGS_WHILE_IN_USE_FIX:
- updateEnableFgsWhileInUseFix();
- break;
case KEY_MAX_PREVIOUS_TIME:
updateMaxPreviousTime();
break;
@@ -2005,12 +1995,6 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION);
}
- private void updateEnableFgsWhileInUseFix() {
- mEnableFgsWhileInUseFix = DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
- KEY_ENABLE_FGS_WHILE_IN_USE_FIX,
- DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX);
- }
private void updateUseTieredCachedAdj() {
USE_TIERED_CACHED_ADJ = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2211,9 +2195,6 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print(" "); pw.print(KEY_SYSTEM_EXEMPT_POWER_RESTRICTIONS_ENABLED);
pw.print("="); pw.println(mFlagSystemExemptPowerRestrictionsEnabled);
- pw.print(" "); pw.print(KEY_ENABLE_FGS_WHILE_IN_USE_FIX);
- pw.print("="); pw.println(mEnableFgsWhileInUseFix);
-
pw.print(" "); pw.print(KEY_SHORT_FGS_TIMEOUT_DURATION);
pw.print("="); pw.println(mShortFgsTimeoutDuration);
pw.print(" "); pw.print(KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3d02c96ae386..5c1dad978095 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1489,12 +1489,10 @@ public class ActivityManagerService extends IActivityManager.Stub
static final class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_FOREGROUND_SERVICES = 1<<1;
- static final int CHANGE_CAPABILITY = 1<<2;
int changes;
int uid;
int pid;
int processState;
- int capability;
boolean foregroundActivities;
int foregroundServiceTypes;
}
@@ -3393,7 +3391,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
}
- ProcessList.killProcessGroup(app.uid, pid);
+ app.killProcessGroupIfNecessaryLocked(true);
synchronized (mProcLock) {
app.setKilled(true);
}
@@ -4854,7 +4852,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
checkTime(startTime, "finishAttachApplicationInner: "
+ "after dispatching broadcasts");
- } catch (Exception e) {
+ } catch (BroadcastDeliveryFailedException e) {
// If the app died trying to launch the receiver we declare it 'bad'
Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
badApp = true;
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 05e1370cd4c9..16f222697646 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1202,6 +1202,14 @@ public class AppProfiler {
mCachedAppsWatermarkData.updateCachedAppsHighWatermarkIfNecessaryLocked(
numCached + numEmpty, now);
+ boolean allChanged;
+ int trackerMemFactor;
+ synchronized (mService.mProcessStats.mLock) {
+ allChanged = mService.mProcessStats.setMemFactorLocked(memFactor,
+ mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(),
+ SystemClock.uptimeMillis() /* re-acquire the time within the lock */);
+ trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
+ }
if (mService.mConstants.USE_MODERN_TRIM) {
// Modern trim is not sent based on lowmem state
@@ -1235,14 +1243,6 @@ public class AppProfiler {
mLastMemoryLevel = memFactor;
mLastNumProcesses = mService.mProcessList.getLruSizeLOSP();
- boolean allChanged;
- int trackerMemFactor;
- synchronized (mService.mProcessStats.mLock) {
- allChanged = mService.mProcessStats.setMemFactorLocked(memFactor,
- mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(),
- SystemClock.uptimeMillis() /* re-acquire the time within the lock */);
- trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
- }
if (memFactor != ADJ_MEM_FACTOR_NORMAL) {
if (mLowRamStartTime == 0) {
mLowRamStartTime = now;
diff --git a/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java b/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java
new file mode 100644
index 000000000000..9c9281635cf7
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.util.AndroidException;
+
+/**
+ * Exception to represent that broadcast could not be delivered.
+ */
+public class BroadcastDeliveryFailedException extends AndroidException {
+ public BroadcastDeliveryFailedException(String name) {
+ super(name);
+ }
+
+ public BroadcastDeliveryFailedException(Exception cause) {
+ super(cause);
+ }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 3ac2b2bd9fd1..0b5b1cb2902e 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -280,6 +280,25 @@ class BroadcastProcessQueue {
}
/**
+ * Re-enqueue the active broadcast so that it can be made active and delivered again. In order
+ * to keep its previous position same to avoid issues with reordering, insert it at the head
+ * of the queue.
+ *
+ * Callers are responsible for clearing the active broadcast by calling
+ * {@link #makeActiveIdle()} after re-enqueuing it.
+ */
+ public void reEnqueueActiveBroadcast() {
+ final BroadcastRecord record = getActive();
+ final int recordIndex = getActiveIndex();
+
+ final SomeArgs broadcastArgs = SomeArgs.obtain();
+ broadcastArgs.arg1 = record;
+ broadcastArgs.argi1 = recordIndex;
+ getQueueForBroadcast(record).addFirst(broadcastArgs);
+ onBroadcastEnqueued(record, recordIndex);
+ }
+
+ /**
* Searches from newest to oldest in the pending broadcast queues, and at the first matching
* pending broadcast it finds, replaces it in-place and returns -- does not attempt to handle
* "duplicate" broadcasts in the queue.
@@ -1015,6 +1034,7 @@ class BroadcastProcessQueue {
static final int REASON_CONTAINS_INSTRUMENTED = 16;
static final int REASON_CONTAINS_MANIFEST = 17;
static final int REASON_FOREGROUND = 18;
+ static final int REASON_CORE_UID = 19;
@IntDef(flag = false, prefix = { "REASON_" }, value = {
REASON_EMPTY,
@@ -1035,6 +1055,7 @@ class BroadcastProcessQueue {
REASON_CONTAINS_INSTRUMENTED,
REASON_CONTAINS_MANIFEST,
REASON_FOREGROUND,
+ REASON_CORE_UID,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Reason {}
@@ -1059,6 +1080,7 @@ class BroadcastProcessQueue {
case REASON_CONTAINS_INSTRUMENTED: return "CONTAINS_INSTRUMENTED";
case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST";
case REASON_FOREGROUND: return "FOREGROUND";
+ case REASON_CORE_UID: return "CORE_UID";
default: return Integer.toString(reason);
}
}
@@ -1103,6 +1125,9 @@ class BroadcastProcessQueue {
} else if (mProcessPersistent) {
mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
mRunnableAtReason = REASON_PERSISTENT;
+ } else if (UserHandle.isCore(uid)) {
+ mRunnableAt = runnableAt;
+ mRunnableAtReason = REASON_CORE_UID;
} else if (mCountOrdered > 0) {
mRunnableAt = runnableAt;
mRunnableAtReason = REASON_CONTAINS_ORDERED;
@@ -1257,7 +1282,7 @@ class BroadcastProcessQueue {
BroadcastProcessQueue test = head;
BroadcastProcessQueue tail = null;
while (test != null) {
- if (test.getRunnableAt() >= itemRunnableAt) {
+ if (test.getRunnableAt() > itemRunnableAt) {
item.runnableAtNext = test;
item.runnableAtPrev = test.runnableAtPrev;
if (item.runnableAtNext != null) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 8e76e5b5cf48..e38a2eefcd92 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -148,7 +148,8 @@ public abstract class BroadcastQueue {
* dispatching a pending broadcast
*/
@GuardedBy("mService")
- public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app);
+ public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
+ throws BroadcastDeliveryFailedException;
/**
* Signal from OS internals that the given process has timed out during
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index e389821595a0..f6004d7d2b7f 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -264,7 +264,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
if (oldRecord.resultTo != null) {
try {
oldRecord.mIsReceiverAppRunning = true;
- performReceiveLocked(oldRecord.resultToApp, oldRecord.resultTo,
+ performReceiveLocked(oldRecord, oldRecord.resultToApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
false, false, oldRecord.shareIdentity, oldRecord.userId,
@@ -438,7 +438,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
scheduleBroadcastsLocked();
}
- public boolean onApplicationAttachedLocked(ProcessRecord app) {
+ public boolean onApplicationAttachedLocked(ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
updateUidReadyForBootCompletedBroadcastLocked(app.uid);
if (mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
@@ -460,7 +461,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
skipCurrentOrPendingReceiverLocked(app);
}
- public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
+ public boolean sendPendingBroadcastsLocked(ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
boolean didSomething = false;
final BroadcastRecord br = mPendingBroadcast;
if (br != null && br.curApp.getPid() > 0 && br.curApp.getPid() == app.getPid()) {
@@ -483,7 +485,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
br.state = BroadcastRecord.IDLE;
- throw new RuntimeException(e.getMessage());
+ throw new BroadcastDeliveryFailedException(e);
}
}
return didSomething;
@@ -613,7 +615,9 @@ public class BroadcastQueueImpl extends BroadcastQueue {
finishTime - r.receiverTime,
packageState,
r.curApp.info.packageName,
- r.callerPackage);
+ r.callerPackage,
+ r.calculateTypeForLogging(),
+ r.getDeliveryGroupPolicy());
}
if (state == BroadcastRecord.IDLE) {
Slog.w(TAG_BROADCAST, "finishReceiver [" + mQueueName + "] called but state is IDLE");
@@ -740,7 +744,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
}
}
- public void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
+ public void performReceiveLocked(BroadcastRecord r, ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, boolean shareIdentity, int sendingUser,
int receiverUid, int callingUid, String callingPackage,
@@ -793,7 +797,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
dispatchDelay, receiveDelay, 0 /* finish_delay */,
SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL,
- app != null ? app.info.packageName : null, callingPackage);
+ app != null ? app.info.packageName : null, callingPackage,
+ r.calculateTypeForLogging(), r.getDeliveryGroupPolicy());
}
}
@@ -869,7 +874,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
maybeAddBackgroundStartPrivileges(filter.receiverList.app, r);
maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
maybeReportBroadcastDispatchedEventLocked(r, filter.owningUid);
- performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
+ performReceiveLocked(r, filter.receiverList.app, filter.receiverList.receiver,
prepareReceiverIntent(r.intent, filteredExtras), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.shareIdentity, r.userId,
filter.receiverList.uid, r.callingUid, r.callerPackage,
@@ -1160,7 +1165,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
r.dispatchTime = now;
}
r.mIsReceiverAppRunning = true;
- performReceiveLocked(r.resultToApp, r.resultTo,
+ performReceiveLocked(r, r.resultToApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.shareIdentity,
r.userId, r.callingUid, r.callingUid, r.callerPackage,
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index f180f02f7742..cbc75401f0b8 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -469,10 +469,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
if (DEBUG_BROADCAST) logv("Promoting " + queue
+ " from runnable to running; process is " + queue.app);
promoteToRunningLocked(queue);
- final boolean completed;
+ boolean completed;
if (processWarm) {
updateOomAdj |= queue.runningOomAdjusted;
- completed = scheduleReceiverWarmLocked(queue);
+ try {
+ completed = scheduleReceiverWarmLocked(queue);
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
+ completed = true;
+ }
} else {
completed = scheduleReceiverColdLocked(queue);
}
@@ -513,7 +518,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
private void clearInvalidPendingColdStart() {
logw("Clearing invalid pending cold start: " + mRunningColdStart);
- onApplicationCleanupLocked(mRunningColdStart.app);
+ mRunningColdStart.reEnqueueActiveBroadcast();
+ demoteFromRunningLocked(mRunningColdStart);
+ clearRunningColdStart();
}
private void checkPendingColdStartValidity() {
@@ -535,8 +542,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ private void reEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
+ checkState(queue.isActive(), "isActive");
+
+ final BroadcastRecord record = queue.getActive();
+ final int index = queue.getActiveIndex();
+ setDeliveryState(queue, queue.app, record, index, record.receivers.get(index),
+ BroadcastRecord.DELIVERY_PENDING, "reEnqueueActiveBroadcast");
+ queue.reEnqueueActiveBroadcast();
+ }
+
@Override
- public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app) {
+ public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
// Process records can be recycled, so always start by looking up the
// relevant per-process queue
final BroadcastProcessQueue queue = getProcessQueue(app);
@@ -557,8 +575,14 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
queue.traceProcessEnd();
queue.traceProcessRunningBegin();
- if (scheduleReceiverWarmLocked(queue)) {
+ try {
+ if (scheduleReceiverWarmLocked(queue)) {
+ demoteFromRunningLocked(queue);
+ }
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
demoteFromRunningLocked(queue);
+ throw e;
}
// We might be willing to kick off another cold start
@@ -588,14 +612,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
- // We've been waiting for this app to cold start, and it had
- // trouble; clear the slot and fail delivery below
- mRunningColdStart = null;
-
- queue.traceProcessEnd();
-
- // We might be willing to kick off another cold start
- enqueueUpdateRunningList();
+ clearRunningColdStart();
}
if (queue != null) {
@@ -618,6 +635,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ private void clearRunningColdStart() {
+ mRunningColdStart.traceProcessEnd();
+
+ // We've been waiting for this app to cold start, and it had
+ // trouble; clear the slot and fail delivery below
+ mRunningColdStart = null;
+
+ // We might be willing to kick off another cold start
+ enqueueUpdateRunningList();
+ }
+
@Override
public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) {
final BroadcastProcessQueue queue = getProcessQueue(app);
@@ -703,8 +731,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
if (mService.shouldIgnoreDeliveryGroupPolicy(r.intent.getAction())) {
return;
}
- final int policy = (r.options != null)
- ? r.options.getDeliveryGroupPolicy() : BroadcastOptions.DELIVERY_GROUP_POLICY_ALL;
+ final int policy = r.getDeliveryGroupPolicy();
final BroadcastConsumer broadcastConsumer;
switch (policy) {
case BroadcastOptions.DELIVERY_GROUP_POLICY_ALL:
@@ -720,6 +747,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// supplied, then ignore the delivery group policy.
return;
}
+ // TODO: Don't merge with the same BroadcastRecord more than once.
broadcastConsumer = (record, recordIndex) -> {
r.intent.mergeExtras(record.intent, extrasMerger);
mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
@@ -730,10 +758,31 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return;
}
forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
+ // If the receiver is already in a terminal state, then ignore it.
+ if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
+ return false;
+ }
// We only allow caller to remove broadcasts they enqueued
- return (r.callingUid == testRecord.callingUid)
- && (r.userId == testRecord.userId)
- && r.matchesDeliveryGroup(testRecord);
+ if ((r.callingUid != testRecord.callingUid)
+ || (r.userId != testRecord.userId)
+ || !r.matchesDeliveryGroup(testRecord)) {
+ return false;
+ }
+ // TODO: If a process is in a deferred state, we can always apply the policy as long
+ // as it is one of the receivers for the new broadcast.
+
+ // For ordered broadcast, check if the receivers for the new broadcast is a superset
+ // of those for the previous one as skipping and removing only one of them could result
+ // in an inconsistent state.
+ if (testRecord.ordered || testRecord.resultTo != null) {
+ // TODO: Cache this result in some way so that we don't have to perform the
+ // same check for all the broadcast receivers.
+ return r.containsAllReceivers(testRecord.receivers);
+ } else if (testRecord.prioritized) {
+ return r.containsAllReceivers(testRecord.receivers);
+ } else {
+ return r.containsReceiver(testRecord.receivers.get(testIndex));
+ }
}, broadcastConsumer, true);
}
@@ -814,7 +863,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
*/
@CheckResult
@GuardedBy("mService")
- private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue) {
+ private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue)
+ throws BroadcastDeliveryFailedException {
checkState(queue.isActive(), "isActive");
final int cookie = traceBegin("scheduleReceiverWarmLocked");
@@ -896,7 +946,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
*/
@CheckResult
private boolean dispatchReceivers(@NonNull BroadcastProcessQueue queue,
- @NonNull BroadcastRecord r, int index) {
+ @NonNull BroadcastRecord r, int index) throws BroadcastDeliveryFailedException {
final ProcessRecord app = queue.app;
final Object receiver = r.receivers.get(index);
@@ -983,6 +1033,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
logw(msg);
app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
+ // If we were trying to deliver a manifest broadcast, throw the error as we need
+ // to try redelivering the broadcast to this receiver.
+ if (receiver instanceof ResolveInfo) {
+ throw new BroadcastDeliveryFailedException(e);
+ }
finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
"remote app");
return false;
@@ -1070,7 +1125,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
boolean waitForServices) {
final BroadcastProcessQueue queue = getProcessQueue(app);
if ((queue == null) || !queue.isActive()) {
- logw("Ignoring finish; no active broadcast for " + queue);
+ logw("Ignoring finishReceiverLocked; no active broadcast for " + queue);
return false;
}
@@ -1107,7 +1162,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// We're on a roll; move onto the next broadcast for this process
queue.makeActiveNextPending();
- if (scheduleReceiverWarmLocked(queue)) {
+ try {
+ if (scheduleReceiverWarmLocked(queue)) {
+ demoteFromRunningLocked(queue);
+ return true;
+ }
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
demoteFromRunningLocked(queue);
return true;
}
@@ -1144,7 +1205,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
private void finishReceiverActiveLocked(@NonNull BroadcastProcessQueue queue,
@DeliveryState int deliveryState, @NonNull String reason) {
if (!queue.isActive()) {
- logw("Ignoring finish; no active broadcast for " + queue);
+ logw("Ignoring finishReceiverActiveLocked; no active broadcast for " + queue);
return;
}
@@ -1870,7 +1931,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
: SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL;
FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, uid, senderUid, actionName,
receiverType, type, dispatchDelay, receiveDelay, finishDelay, packageState,
- app != null ? app.info.packageName : null, r.callerPackage);
+ app != null ? app.info.packageName : null, r.callerPackage,
+ r.calculateTypeForLogging(), r.getDeliveryGroupPolicy());
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a402db945321..cfdb13393e80 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -17,6 +17,19 @@
package com.android.server.am;
import static android.app.ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_ALARM;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_BACKGROUND;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_FOREGROUND;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_INITIAL_STICKY;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_INTERACTIVE;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_NONE;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_PRIORITIZED;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY;
import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_ALL;
import static com.android.server.am.BroadcastConstants.DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY;
@@ -35,6 +48,7 @@ import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
+import android.app.BroadcastOptions.DeliveryGroupPolicy;
import android.app.compat.CompatChanges;
import android.content.ComponentName;
import android.content.IIntentReceiver;
@@ -699,6 +713,9 @@ final class BroadcastRecord extends Binder {
break;
}
switch (newDeliveryState) {
+ case DELIVERY_PENDING:
+ scheduledTime[index] = 0;
+ break;
case DELIVERY_SCHEDULED:
scheduledTime[index] = SystemClock.uptimeMillis();
break;
@@ -1015,6 +1032,46 @@ final class BroadcastRecord extends Binder {
}
}
+ int calculateTypeForLogging() {
+ int type = BROADCAST_TYPE_NONE;
+ if (isForeground()) {
+ type |= BROADCAST_TYPE_FOREGROUND;
+ } else {
+ type |= BROADCAST_TYPE_BACKGROUND;
+ }
+ if (alarm) {
+ type |= BROADCAST_TYPE_ALARM;
+ }
+ if (interactive) {
+ type |= BROADCAST_TYPE_INTERACTIVE;
+ }
+ if (ordered) {
+ type |= BROADCAST_TYPE_ORDERED;
+ }
+ if (prioritized) {
+ type |= BROADCAST_TYPE_PRIORITIZED;
+ }
+ if (resultTo != null) {
+ type |= BROADCAST_TYPE_RESULT_TO;
+ }
+ if (deferUntilActive) {
+ type |= BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE;
+ }
+ if (pushMessage) {
+ type |= BROADCAST_TYPE_PUSH_MESSAGE;
+ }
+ if (pushMessageOverQuota) {
+ type |= BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA;
+ }
+ if (sticky) {
+ type |= BROADCAST_TYPE_STICKY;
+ }
+ if (initialSticky) {
+ type |= BROADCAST_TYPE_INITIAL_STICKY;
+ }
+ return type;
+ }
+
public BroadcastRecord maybeStripForHistory() {
if (!intent.canStripForHistory()) {
return this;
@@ -1092,6 +1149,30 @@ final class BroadcastRecord extends Binder {
}
}
+ boolean containsReceiver(@NonNull Object receiver) {
+ for (int i = receivers.size() - 1; i >= 0; --i) {
+ if (isReceiverEquals(receiver, receivers.get(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean containsAllReceivers(@NonNull List<Object> otherReceivers) {
+ for (int i = otherReceivers.size() - 1; i >= 0; --i) {
+ if (!containsReceiver(otherReceivers.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @DeliveryGroupPolicy
+ int getDeliveryGroupPolicy() {
+ return (options != null) ? options.getDeliveryGroupPolicy()
+ : BroadcastOptions.DELIVERY_GROUP_POLICY_ALL;
+ }
+
boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
return matchesDeliveryGroup(this, other);
}
diff --git a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
index 9b3f24933f02..80406e6f66e4 100644
--- a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
+++ b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
@@ -34,8 +34,11 @@ import android.app.ForegroundServiceDelegationOptions;
import android.content.ComponentName;
import android.content.pm.ServiceInfo;
import android.util.ArrayMap;
+import android.util.IntArray;
+import android.util.LongArray;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
@@ -90,13 +93,13 @@ public class ForegroundServiceTypeLoggerModule {
// These counts will only be added to the open call count below if
// an FGS is started. If an FGS is NOT started, then this count should
// gradually hit zero as close calls are decremented.
- final SparseArray<Integer> mOpenedWithoutFgsCount = new SparseArray<>();
+ final SparseIntArray mOpenedWithoutFgsCount = new SparseIntArray();
// Here we keep track of the count of in-flight calls.
// We only want to log the first open call and the last
// close call so that we get the largest duration
// possible.
- final SparseArray<Integer> mOpenWithFgsCount = new SparseArray<>();
+ final SparseIntArray mOpenWithFgsCount = new SparseIntArray();
// A stack that keeps a list of API calls in the order
// that they were called. This represents the ongoing
@@ -131,12 +134,12 @@ public class ForegroundServiceTypeLoggerModule {
mUids.put(uid, uidState);
}
// grab the appropriate types
- final ArrayList<Integer> apiTypes =
+ final IntArray apiTypes =
convertFgsTypeToApiTypes(record.foregroundServiceType);
// now we need to iterate through the types
// and insert the new record as needed
- final ArrayList<Integer> apiTypesFound = new ArrayList<>();
- final ArrayList<Long> timestampsFound = new ArrayList<>();
+ final IntArray apiTypesFound = new IntArray();
+ final LongArray timestampsFound = new LongArray();
for (int i = 0, size = apiTypes.size(); i < size; i++) {
final int apiType = apiTypes.get(i);
int fgsIndex = uidState.mRunningFgs.indexOfKey(apiType);
@@ -170,7 +173,7 @@ public class ForegroundServiceTypeLoggerModule {
uidState.mApiOpenCalls.remove(apiType);
}
}
- if (!apiTypesFound.isEmpty()) {
+ if (apiTypesFound.size() != 0) {
// log a state change
for (int i = 0, size = apiTypesFound.size(); i < size; i++) {
logFgsApiEvent(record,
@@ -190,7 +193,7 @@ public class ForegroundServiceTypeLoggerModule {
// we need to log all the API end events and remove the start events
// then we remove the FGS from the various stacks
// and also clean up the start calls stack by UID
- final ArrayList<Integer> apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
+ final IntArray apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
final UidState uidState = mUids.get(uid);
if (uidState == null) {
Slog.w(TAG, "FGS stop call being logged with no start call for UID for UID "
@@ -202,7 +205,8 @@ public class ForegroundServiceTypeLoggerModule {
final ArrayList<Long> timestampsFound = new ArrayList<>();
for (int i = 0, size = apiTypes.size(); i < size; i++) {
final int apiType = apiTypes.get(i);
- if (!uidState.mOpenWithFgsCount.contains(apiType)) {
+ final int apiTypeIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
+ if (apiTypeIndex < 0) {
Slog.w(TAG, "Logger should be tracking FGS types correctly for UID " + uid
+ " in package " + record.packageName);
continue;
@@ -213,7 +217,7 @@ public class ForegroundServiceTypeLoggerModule {
// we just skip logging
final FgsApiRecord closedApi = uidState.mApiClosedCalls.get(apiType);
if (closedApi != null
- && uidState.mOpenWithFgsCount.get(apiType) == 0) {
+ && uidState.mOpenWithFgsCount.valueAt(apiTypeIndex) == 0) {
apisFound.add(apiType);
timestampsFound.add(closedApi.mTimeStart);
// remove the last API close call
@@ -332,7 +336,8 @@ public class ForegroundServiceTypeLoggerModule {
Slog.w(TAG, "API event end called before start!");
return -1;
}
- if (uidState.mOpenWithFgsCount.contains(apiType)) {
+ final int apiIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
+ if (apiIndex >= 0) {
// are there any calls that started with an FGS?
if (uidState.mOpenWithFgsCount.get(apiType) != 0) {
// we should decrement the count, since we only
@@ -351,7 +356,7 @@ public class ForegroundServiceTypeLoggerModule {
logFgsApiEventWithNoFgs(uid, FGS_API_END_WITHOUT_FGS, apiTypes, timestamp);
// we should now remove the count, so as to signal that
// there was never an FGS called that can be associated
- uidState.mOpenWithFgsCount.remove(apiType);
+ uidState.mOpenWithFgsCount.removeAt(apiIndex);
return timestamp;
}
}
@@ -359,7 +364,7 @@ public class ForegroundServiceTypeLoggerModule {
// open FGS associated API call. So it is likely
// a part of an unassociated call that has now been
// closed. So we decrement that count
- if (!uidState.mOpenedWithoutFgsCount.contains(apiType)) {
+ if (uidState.mOpenedWithoutFgsCount.indexOfKey(apiType) < 0) {
// initialize if we don't contain
uidState.mOpenedWithoutFgsCount.put(apiType, 0);
}
@@ -402,8 +407,8 @@ public class ForegroundServiceTypeLoggerModule {
}
}
- private ArrayList<Integer> convertFgsTypeToApiTypes(int fgsType) {
- final ArrayList<Integer> types = new ArrayList<>();
+ private IntArray convertFgsTypeToApiTypes(int fgsType) {
+ final IntArray types = new IntArray();
if ((fgsType & ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA)
== ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA) {
types.add(FOREGROUND_SERVICE_API_TYPE_CAMERA);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 1e5f187fee4a..a86c2e362c54 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -837,7 +837,7 @@ public class OomAdjuster {
*/
@GuardedBy("mService")
void enqueueOomAdjTargetLocked(ProcessRecord app) {
- if (app != null) {
+ if (app != null && app.mState.getMaxAdj() > FOREGROUND_APP_ADJ) {
mPendingProcessSet.add(app);
}
}
@@ -3188,7 +3188,6 @@ public class OomAdjuster {
}
if (state.getCurCapability() != state.getSetCapability()) {
- changes |= ActivityManagerService.ProcessChangeItem.CHANGE_CAPABILITY;
state.setSetCapability(state.getCurCapability());
}
@@ -3212,13 +3211,12 @@ public class OomAdjuster {
mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid);
item.changes |= changes;
item.foregroundActivities = state.hasRepForegroundActivities();
- item.capability = state.getSetCapability();
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
"Item " + Integer.toHexString(System.identityHashCode(item))
+ " " + app.toShortString() + ": changes=" + item.changes
+ " foreground=" + item.foregroundActivities
+ " type=" + state.getAdjType() + " source=" + state.getAdjSource()
- + " target=" + state.getAdjTarget() + " capability=" + item.capability);
+ + " target=" + state.getAdjTarget());
}
if (state.isCached() && !state.shouldNotKillOnBgRestrictedAndIdle()) {
@@ -3253,7 +3251,11 @@ public class OomAdjuster {
// {@link SCHED_GROUP_TOP_APP}. We don't check render thread because it
// is not ready when attaching.
app.getWindowProcessController().onTopProcChanged();
- setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
+ if (mService.mUseFifoUiScheduling) {
+ mService.scheduleAsFifoPriority(app.getPid(), true);
+ } else {
+ setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
+ }
initialSchedGroup = SCHED_GROUP_TOP_APP;
} catch (Exception e) {
Slog.w(TAG, "Failed to pre-set top priority to " + app + " " + e);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 335d6768c37b..d6495c78574c 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1197,26 +1197,7 @@ class ProcessRecord implements WindowProcessListener {
EventLog.writeEvent(EventLogTags.AM_KILL,
userId, mPid, processName, mState.getSetAdj(), reason);
Process.killProcessQuiet(mPid);
- final boolean killProcessGroup;
- if (mHostingRecord != null
- && (mHostingRecord.usesWebviewZygote() || mHostingRecord.usesAppZygote())) {
- synchronized (ProcessRecord.this) {
- killProcessGroup = mProcessGroupCreated;
- if (!killProcessGroup) {
- // The process group hasn't been created, request to skip it.
- mSkipProcessGroupCreation = true;
- }
- }
- } else {
- killProcessGroup = true;
- }
- if (killProcessGroup) {
- if (asyncKPG) {
- ProcessList.killProcessGroup(uid, mPid);
- } else {
- Process.sendSignalToProcessGroup(uid, mPid, OsConstants.SIGKILL);
- }
- }
+ killProcessGroupIfNecessaryLocked(asyncKPG);
} else {
mPendingStart = false;
}
@@ -1231,6 +1212,30 @@ class ProcessRecord implements WindowProcessListener {
}
}
+ @GuardedBy("mService")
+ void killProcessGroupIfNecessaryLocked(boolean async) {
+ final boolean killProcessGroup;
+ if (mHostingRecord != null
+ && (mHostingRecord.usesWebviewZygote() || mHostingRecord.usesAppZygote())) {
+ synchronized (ProcessRecord.this) {
+ killProcessGroup = mProcessGroupCreated;
+ if (!killProcessGroup) {
+ // The process group hasn't been created, request to skip it.
+ mSkipProcessGroupCreation = true;
+ }
+ }
+ } else {
+ killProcessGroup = true;
+ }
+ if (killProcessGroup) {
+ if (async) {
+ ProcessList.killProcessGroup(uid, mPid);
+ } else {
+ Process.sendSignalToProcessGroup(uid, mPid, OsConstants.SIGKILL);
+ }
+ }
+ }
+
@Override
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
dumpDebug(proto, fieldId, -1);
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 81d0b6ac700b..7ff6d116baaf 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -341,7 +341,8 @@ final class ProcessServiceRecord {
mHasAboveClient = false;
for (int i = mConnections.size() - 1; i >= 0; i--) {
ConnectionRecord cr = mConnections.valueAt(i);
- if (cr.hasFlag(Context.BIND_ABOVE_CLIENT)) {
+ if (cr.binding.service.app.mServices != this
+ && cr.hasFlag(Context.BIND_ABOVE_CLIENT)) {
mHasAboveClient = true;
break;
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 1f39d1b5d7f8..dccbb0accadd 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -177,12 +177,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
@PowerExemptionManager.ReasonCode
int mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
- // Integer version of mAllowWhileInUsePermissionInFgs that we keep track to compare
- // the old and new logics.
- // TODO: Remove them once we're confident in the new logic.
- int mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
- int mDebugWhileInUseReasonInBindService = REASON_DENIED;
-
// A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state.
boolean mAllowWhileInUsePermissionInFgsAtEntering;
/** Allow scheduling user-initiated jobs from the background. */
@@ -224,13 +218,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// is called.
int mStartForegroundCount;
- // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground was set to "allowed"
- // from "disallowed" when the service was _not_ already a foreground service.
- // this means they're set in startService(). (not startForegroundService)
- // In startForeground(), if this timestamp is too old, we can't trust these flags, so
- // we need to reset them.
- long mLastUntrustedSetFgsRestrictionAllowedTime;
-
// This is a service record of a FGS delegate (not a service record of a real service)
boolean mIsFgsDelegate;
@Nullable ForegroundServiceDelegation mFgsDelegation;
@@ -624,12 +611,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("mAllowWhileInUsePermissionInFgsReason=");
pw.println(PowerExemptionManager.reasonCodeToString(mAllowWhileInUsePermissionInFgsReason));
- pw.print(prefix); pw.print("debugWhileInUseReasonInStartForeground=");
- pw.println(PowerExemptionManager.reasonCodeToString(
- mDebugWhileInUseReasonInStartForeground));
- pw.print(prefix); pw.print("debugWhileInUseReasonInBindService=");
- pw.println(PowerExemptionManager.reasonCodeToString(mDebugWhileInUseReasonInBindService));
-
pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling);
pw.print(prefix); pw.print("recentCallingPackage=");
pw.println(mRecentCallingPackage);
@@ -642,10 +623,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("infoAllowStartForeground=");
pw.println(mInfoAllowStartForeground);
- pw.print(prefix); pw.print("lastUntrustedSetFgsRestrictionAllowedTime=");
- TimeUtils.formatDuration(mLastUntrustedSetFgsRestrictionAllowedTime, now, pw);
- pw.println();
-
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 12bb5d23e4cf..76a994ec63e9 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -151,6 +151,8 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -1707,7 +1709,8 @@ class UserController implements Handler.Callback {
mInjector.getWindowManager().setSwitchingUser(true);
// Only lock if the user has a secure keyguard PIN/Pattern/Pwd
if (mInjector.getKeyguardManager().isDeviceSecure(userId)) {
- mInjector.getWindowManager().lockNow(null);
+ // Make sure the device is locked before moving on with the user switch
+ mInjector.lockDeviceNowAndWaitForKeyguardShown();
}
}
@@ -3444,6 +3447,11 @@ class UserController implements Handler.Callback {
WindowManagerService getWindowManager() {
return mService.mWindowManager;
}
+
+ ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+ return mService.mAtmInternal;
+ }
+
void activityManagerOnUserStopped(@UserIdInt int userId) {
LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
}
@@ -3667,5 +3675,43 @@ class UserController implements Handler.Callback {
void onSystemUserVisibilityChanged(boolean visible) {
getUserManagerInternal().onSystemUserVisibilityChanged(visible);
}
+
+ void lockDeviceNowAndWaitForKeyguardShown() {
+ if (getWindowManager().isKeyguardLocked()) {
+ return;
+ }
+
+ final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+ t.traceBegin("lockDeviceNowAndWaitForKeyguardShown");
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ ActivityTaskManagerInternal.ScreenObserver screenObserver =
+ new ActivityTaskManagerInternal.ScreenObserver() {
+ @Override
+ public void onAwakeStateChanged(boolean isAwake) {
+
+ }
+
+ @Override
+ public void onKeyguardStateChanged(boolean isShowing) {
+ if (isShowing) {
+ latch.countDown();
+ }
+ }
+ };
+
+ getActivityTaskManagerInternal().registerScreenObserver(screenObserver);
+ getWindowManager().lockDeviceNow();
+ try {
+ if (!latch.await(20, TimeUnit.SECONDS)) {
+ throw new RuntimeException("Keyguard is not shown in 20 seconds");
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ getActivityTaskManagerInternal().unregisterScreenObserver(screenObserver);
+ t.traceEnd();
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 1f3795a12b76..a110169ac8c2 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -44,7 +44,6 @@ import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
import static android.app.AppOpsManager.OP_RECORD_AUDIO_SANDBOXED;
-import static android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
import static android.app.AppOpsManager.OP_VIBRATE;
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
@@ -1770,11 +1769,6 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public void setUidMode(int code, int uid, int mode) {
setUidMode(code, uid, mode, null);
- if (code == OP_RUN_ANY_IN_BACKGROUND) {
- // TODO (b/280869337): Remove this once we have the required data.
- Slog.wtfStack(TAG, "setUidMode called for RUN_ANY_IN_BACKGROUND by uid: "
- + UserHandle.formatUid(Binder.getCallingUid()));
- }
}
private void setUidMode(int code, int uid, int mode,
@@ -1950,17 +1944,6 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public void setMode(int code, int uid, @NonNull String packageName, int mode) {
setMode(code, uid, packageName, mode, null);
- final int callingUid = Binder.getCallingUid();
- if (code == OP_RUN_ANY_IN_BACKGROUND && mode != MODE_ALLOWED) {
- // TODO (b/280869337): Remove this once we have the required data.
- final String callingPackage = ArrayUtils.firstOrNull(getPackagesForUid(callingUid));
- Slog.wtfStack(TAG,
- "RUN_ANY_IN_BACKGROUND for package " + packageName + " changed to mode: "
- + modeToName(mode) + " via setMode. Calling package: " + callingPackage
- + ", calling uid: " + UserHandle.formatUid(callingUid)
- + ", calling pid: " + Binder.getCallingPid()
- + ", system pid: " + Process.myPid());
- }
}
void setMode(int code, int uid, @NonNull String packageName, int mode,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index d7a5ee963449..b86da88d15c3 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -2205,19 +2205,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
if (preferredCommunicationDevice == null) {
AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
if (defaultDevice != null) {
- mDeviceInventory.setPreferredDevicesForStrategy(
+ mDeviceInventory.setPreferredDevicesForStrategyInt(
mCommunicationStrategyId, Arrays.asList(defaultDevice));
- mDeviceInventory.setPreferredDevicesForStrategy(
+ mDeviceInventory.setPreferredDevicesForStrategyInt(
mAccessibilityStrategyId, Arrays.asList(defaultDevice));
} else {
- mDeviceInventory.removePreferredDevicesForStrategy(mCommunicationStrategyId);
- mDeviceInventory.removePreferredDevicesForStrategy(mAccessibilityStrategyId);
+ mDeviceInventory.removePreferredDevicesForStrategInt(mCommunicationStrategyId);
+ mDeviceInventory.removePreferredDevicesForStrategInt(mAccessibilityStrategyId);
}
mDeviceInventory.applyConnectedDevicesRoles();
} else {
- mDeviceInventory.setPreferredDevicesForStrategy(
+ mDeviceInventory.setPreferredDevicesForStrategyInt(
mCommunicationStrategyId, Arrays.asList(preferredCommunicationDevice));
- mDeviceInventory.setPreferredDevicesForStrategy(
+ mDeviceInventory.setPreferredDevicesForStrategyInt(
mAccessibilityStrategyId, Arrays.asList(preferredCommunicationDevice));
}
onUpdatePhoneStrategyDevice(preferredCommunicationDevice);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index a561612b99c6..7b2e732702a3 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -67,6 +67,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
+import java.util.stream.Stream;
/**
* Class to manage the inventory of all connected devices.
@@ -324,14 +325,22 @@ public class AudioDeviceInventory {
mPreferredDevicesForCapturePreset.forEach((capturePreset, devices) -> {
pw.println(" " + prefix + "capturePreset:" + capturePreset
+ " devices:" + devices); });
- pw.println("\n" + prefix + "Applied devices roles for strategies:");
+ pw.println("\n" + prefix + "Applied devices roles for strategies (from API):");
mAppliedStrategyRoles.forEach((key, devices) -> {
pw.println(" " + prefix + "strategy: " + key.first
+ " role:" + key.second + " devices:" + devices); });
- pw.println("\n" + prefix + "Applied devices roles for presets:");
+ pw.println("\n" + prefix + "Applied devices roles for strategies (internal):");
+ mAppliedStrategyRolesInt.forEach((key, devices) -> {
+ pw.println(" " + prefix + "strategy: " + key.first
+ + " role:" + key.second + " devices:" + devices); });
+ pw.println("\n" + prefix + "Applied devices roles for presets (from API):");
mAppliedPresetRoles.forEach((key, devices) -> {
pw.println(" " + prefix + "preset: " + key.first
+ " role:" + key.second + " devices:" + devices); });
+ pw.println("\n" + prefix + "Applied devices roles for presets (internal:");
+ mAppliedPresetRolesInt.forEach((key, devices) -> {
+ pw.println(" " + prefix + "preset: " + key.first
+ + " role:" + key.second + " devices:" + devices); });
}
//------------------------------------------------------------
@@ -353,6 +362,9 @@ public class AudioDeviceInventory {
di.mDeviceCodecFormat);
}
mAppliedStrategyRoles.clear();
+ mAppliedStrategyRolesInt.clear();
+ mAppliedPresetRoles.clear();
+ mAppliedPresetRolesInt.clear();
applyConnectedDevicesRoles_l();
}
synchronized (mPreferredDevices) {
@@ -361,8 +373,8 @@ public class AudioDeviceInventory {
}
synchronized (mNonDefaultDevices) {
mNonDefaultDevices.forEach((strategy, devices) -> {
- addDevicesRoleForStrategy(
- strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices); });
+ addDevicesRoleForStrategy(strategy, AudioSystem.DEVICE_ROLE_DISABLED,
+ devices, false /* internal */); });
}
synchronized (mPreferredDevicesForCapturePreset) {
// TODO: call audiosystem to restore
@@ -768,7 +780,7 @@ public class AudioDeviceInventory {
}
return status;
}
-
+ // Only used for external requests coming from an API
/*package*/ int setPreferredDevicesForStrategy(int strategy,
@NonNull List<AudioDeviceAttributes> devices) {
int status = AudioSystem.ERROR;
@@ -777,10 +789,17 @@ public class AudioDeviceInventory {
"setPreferredDevicesForStrategy, strategy: " + strategy
+ " devices: " + devices)).printLog(TAG));
status = setDevicesRoleForStrategy(
- strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices, false /* internal */);
}
return status;
}
+ // Only used for internal requests
+ /*package*/ int setPreferredDevicesForStrategyInt(int strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
+
+ return setDevicesRoleForStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices, true /* internal */);
+ }
/*package*/ int removePreferredDevicesForStrategyAndSave(int strategy) {
final int status = removePreferredDevicesForStrategy(strategy);
@@ -789,7 +808,7 @@ public class AudioDeviceInventory {
}
return status;
}
-
+ // Only used for external requests coming from an API
/*package*/ int removePreferredDevicesForStrategy(int strategy) {
int status = AudioSystem.ERROR;
@@ -799,10 +818,15 @@ public class AudioDeviceInventory {
+ strategy)).printLog(TAG));
status = clearDevicesRoleForStrategy(
- strategy, AudioSystem.DEVICE_ROLE_PREFERRED);
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, false /*internal */);
}
return status;
}
+ // Only used for internal requests
+ /*package*/ int removePreferredDevicesForStrategInt(int strategy) {
+ return clearDevicesRoleForStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, true /*internal */);
+ }
/*package*/ int setDeviceAsNonDefaultForStrategyAndSave(int strategy,
@NonNull AudioDeviceAttributes device) {
@@ -816,7 +840,7 @@ public class AudioDeviceInventory {
"setDeviceAsNonDefaultForStrategyAndSave, strategy: " + strategy
+ " device: " + device)).printLog(TAG));
status = addDevicesRoleForStrategy(
- strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
+ strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices, false /* internal */);
}
if (status == AudioSystem.SUCCESS) {
@@ -838,7 +862,7 @@ public class AudioDeviceInventory {
+ strategy + " devices: " + device)).printLog(TAG));
status = removeDevicesRoleForStrategy(
- strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
+ strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices, false /* internal */);
}
if (status == AudioSystem.SUCCESS) {
@@ -877,6 +901,7 @@ public class AudioDeviceInventory {
return status;
}
+ // Only used for external requests coming from an API
private int setPreferredDevicesForCapturePreset(
int capturePreset, @NonNull List<AudioDeviceAttributes> devices) {
int status = AudioSystem.ERROR;
@@ -895,6 +920,7 @@ public class AudioDeviceInventory {
return status;
}
+ // Only used for external requests coming from an API
private int clearPreferredDevicesForCapturePreset(int capturePreset) {
int status = AudioSystem.ERROR;
@@ -905,20 +931,23 @@ public class AudioDeviceInventory {
return status;
}
- private int addDevicesRoleForCapturePreset(int capturePreset, int role,
+ // Only used for internal requests
+ private int addDevicesRoleForCapturePresetInt(int capturePreset, int role,
@NonNull List<AudioDeviceAttributes> devices) {
- return addDevicesRole(mAppliedPresetRoles, (p, r, d) -> {
+ return addDevicesRole(mAppliedPresetRolesInt, (p, r, d) -> {
return mAudioSystem.addDevicesRoleForCapturePreset(p, r, d);
}, capturePreset, role, devices);
}
- private int removeDevicesRoleForCapturePreset(int capturePreset, int role,
+ // Only used for internal requests
+ private int removeDevicesRoleForCapturePresetInt(int capturePreset, int role,
@NonNull List<AudioDeviceAttributes> devices) {
- return removeDevicesRole(mAppliedPresetRoles, (p, r, d) -> {
+ return removeDevicesRole(mAppliedPresetRolesInt, (p, r, d) -> {
return mAudioSystem.removeDevicesRoleForCapturePreset(p, r, d);
}, capturePreset, role, devices);
}
+ // Only used for external requests coming from an API
private int setDevicesRoleForCapturePreset(int capturePreset, int role,
@NonNull List<AudioDeviceAttributes> devices) {
return setDevicesRole(mAppliedPresetRoles, (p, r, d) -> {
@@ -928,6 +957,7 @@ public class AudioDeviceInventory {
}, capturePreset, role, devices);
}
+ // Only used for external requests coming from an API
private int clearDevicesRoleForCapturePreset(int capturePreset, int role) {
return clearDevicesRole(mAppliedPresetRoles, (p, r, d) -> {
return mAudioSystem.clearDevicesRoleForCapturePreset(p, r);
@@ -945,32 +975,39 @@ public class AudioDeviceInventory {
}
private int addDevicesRoleForStrategy(int strategy, int role,
- @NonNull List<AudioDeviceAttributes> devices) {
- return addDevicesRole(mAppliedStrategyRoles, (s, r, d) -> {
- return mAudioSystem.setDevicesRoleForStrategy(s, r, d);
- }, strategy, role, devices);
+ @NonNull List<AudioDeviceAttributes> devices,
+ boolean internal) {
+ return addDevicesRole(internal ? mAppliedStrategyRolesInt : mAppliedStrategyRoles,
+ (s, r, d) -> {
+ return mAudioSystem.setDevicesRoleForStrategy(s, r, d);
+ }, strategy, role, devices);
}
private int removeDevicesRoleForStrategy(int strategy, int role,
- @NonNull List<AudioDeviceAttributes> devices) {
- return removeDevicesRole(mAppliedStrategyRoles, (s, r, d) -> {
- return mAudioSystem.removeDevicesRoleForStrategy(s, r, d);
- }, strategy, role, devices);
+ @NonNull List<AudioDeviceAttributes> devices,
+ boolean internal) {
+ return removeDevicesRole(internal ? mAppliedStrategyRolesInt : mAppliedStrategyRoles,
+ (s, r, d) -> {
+ return mAudioSystem.removeDevicesRoleForStrategy(s, r, d);
+ }, strategy, role, devices);
}
private int setDevicesRoleForStrategy(int strategy, int role,
- @NonNull List<AudioDeviceAttributes> devices) {
- return setDevicesRole(mAppliedStrategyRoles, (s, r, d) -> {
- return mAudioSystem.setDevicesRoleForStrategy(s, r, d);
- }, (s, r, d) -> {
- return mAudioSystem.clearDevicesRoleForStrategy(s, r);
- }, strategy, role, devices);
+ @NonNull List<AudioDeviceAttributes> devices,
+ boolean internal) {
+ return setDevicesRole(internal ? mAppliedStrategyRolesInt : mAppliedStrategyRoles,
+ (s, r, d) -> {
+ return mAudioSystem.setDevicesRoleForStrategy(s, r, d);
+ }, (s, r, d) -> {
+ return mAudioSystem.clearDevicesRoleForStrategy(s, r);
+ }, strategy, role, devices);
}
- private int clearDevicesRoleForStrategy(int strategy, int role) {
- return clearDevicesRole(mAppliedStrategyRoles, (s, r, d) -> {
- return mAudioSystem.clearDevicesRoleForStrategy(s, r);
- }, strategy, role);
+ private int clearDevicesRoleForStrategy(int strategy, int role, boolean internal) {
+ return clearDevicesRole(internal ? mAppliedStrategyRolesInt : mAppliedStrategyRoles,
+ (s, r, d) -> {
+ return mAudioSystem.clearDevicesRoleForStrategy(s, r);
+ }, strategy, role);
}
//------------------------------------------------------------
@@ -978,16 +1015,25 @@ public class AudioDeviceInventory {
// same list of devices for a given role and strategy and the corresponding systematic
// redundant work in audio policy manager and audio flinger.
// The key is the pair <Strategy , Role> and the value is the current list of devices.
-
+ // mAppliedStrategyRoles is for requests coming from an API.
+ // mAppliedStrategyRolesInt is for internal requests. Entries are removed when the requested
+ // device is disconnected.
private final ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>>
mAppliedStrategyRoles = new ArrayMap<>();
+ private final ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>>
+ mAppliedStrategyRolesInt = new ArrayMap<>();
// Cache for applied roles for capture presets and devices. The cache avoids reapplying the
// same list of devices for a given role and capture preset and the corresponding systematic
// redundant work in audio policy manager and audio flinger.
// The key is the pair <Preset , Role> and the value is the current list of devices.
+ // mAppliedPresetRoles is for requests coming from an API.
+ // mAppliedPresetRolesInt is for internal requests. Entries are removed when the requested
+ // device is disconnected.
private final ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>>
mAppliedPresetRoles = new ArrayMap<>();
+ private final ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>>
+ mAppliedPresetRolesInt = new ArrayMap<>();
interface AudioSystemInterface {
int deviceRoleAction(int usecase, int role, @Nullable List<AudioDeviceAttributes> devices);
@@ -1113,9 +1159,9 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void purgeDevicesRoles_l() {
- purgeRoles(mAppliedStrategyRoles, (s, r, d) -> {
+ purgeRoles(mAppliedStrategyRolesInt, (s, r, d) -> {
return mAudioSystem.removeDevicesRoleForStrategy(s, r, d); });
- purgeRoles(mAppliedPresetRoles, (p, r, d) -> {
+ purgeRoles(mAppliedPresetRolesInt, (p, r, d) -> {
return mAudioSystem.removeDevicesRoleForCapturePreset(p, r, d); });
}
@@ -1124,8 +1170,12 @@ public class AudioDeviceInventory {
ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>> rolesMap,
AudioSystemInterface asi) {
synchronized (rolesMap) {
+ AudioDeviceInfo[] connectedDevices = AudioManager.getDevicesStatic(
+ AudioManager.GET_DEVICES_ALL);
+
Iterator<Map.Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>>> itRole =
rolesMap.entrySet().iterator();
+
while (itRole.hasNext()) {
Map.Entry<Pair<Integer, Integer>, List<AudioDeviceAttributes>> entry =
itRole.next();
@@ -1133,9 +1183,15 @@ public class AudioDeviceInventory {
Iterator<AudioDeviceAttributes> itDev = rolesMap.get(keyRole).iterator();
while (itDev.hasNext()) {
AudioDeviceAttributes ada = itDev.next();
- final String devKey = DeviceInfo.makeDeviceListKey(ada.getInternalType(),
- ada.getAddress());
- if (mConnectedDevices.get(devKey) == null) {
+
+ AudioDeviceInfo device = Stream.of(connectedDevices)
+ .filter(d -> d.getInternalType() == ada.getInternalType())
+ .filter(d -> (!AudioSystem.isBluetoothDevice(d.getInternalType())
+ || (d.getAddress() == ada.getAddress())))
+ .findFirst()
+ .orElse(null);
+
+ if (device == null) {
asi.deviceRoleAction(keyRole.first, keyRole.second, Arrays.asList(ada));
itDev.remove();
}
@@ -1582,10 +1638,12 @@ public class AudioDeviceInventory {
}
if (disable) {
addDevicesRoleForStrategy(strategy.getId(),
- AudioSystem.DEVICE_ROLE_DISABLED, Arrays.asList(ada));
+ AudioSystem.DEVICE_ROLE_DISABLED,
+ Arrays.asList(ada), true /* internal */);
} else {
removeDevicesRoleForStrategy(strategy.getId(),
- AudioSystem.DEVICE_ROLE_DISABLED, Arrays.asList(ada));
+ AudioSystem.DEVICE_ROLE_DISABLED,
+ Arrays.asList(ada), true /* internal */);
}
}
}
@@ -1602,10 +1660,10 @@ public class AudioDeviceInventory {
+ ", disable: " + disable);
}
if (disable) {
- addDevicesRoleForCapturePreset(capturePreset,
+ addDevicesRoleForCapturePresetInt(capturePreset,
AudioSystem.DEVICE_ROLE_DISABLED, Arrays.asList(ada));
} else {
- removeDevicesRoleForCapturePreset(capturePreset,
+ removeDevicesRoleForCapturePresetInt(capturePreset,
AudioSystem.DEVICE_ROLE_DISABLED, Arrays.asList(ada));
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index bb04c35c46a2..d0b6cdce037f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1145,6 +1145,11 @@ public class AudioService extends IAudioService.Stub
MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
}
+ int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
+ if (minAssistantVolume != -1) {
+ MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
+ }
+
// Read following properties to configure max volume (number of steps) and default volume
// for STREAM_NOTIFICATION and STREAM_RING:
// config_audio_notif_vol_default
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 1989bc77583a..8ef2a1bd26c2 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -76,7 +76,7 @@ import java.util.function.Function;
*/
public final class AuthSession implements IBinder.DeathRecipient {
private static final String TAG = "BiometricService/AuthSession";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
/*
* Defined in biometrics.proto
@@ -118,6 +118,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
@VisibleForTesting final IBinder mToken;
// Info to be shown on BiometricDialog when all cookies are returned.
@VisibleForTesting final PromptInfo mPromptInfo;
+ @VisibleForTesting final BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
private final long mRequestId;
private final long mOperationId;
private final int mUserId;
@@ -164,6 +165,32 @@ public final class AuthSession implements IBinder.DeathRecipient {
@NonNull PromptInfo promptInfo,
boolean debugEnabled,
@NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) {
+ this(context, biometricContext, statusBarService, sysuiReceiver, keystore, random,
+ clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId,
+ sensorReceiver, clientReceiver, opPackageName, promptInfo, debugEnabled,
+ fingerprintSensorProperties, BiometricFrameworkStatsLogger.getInstance());
+ }
+
+ @VisibleForTesting
+ AuthSession(@NonNull Context context,
+ @NonNull BiometricContext biometricContext,
+ @NonNull IStatusBarService statusBarService,
+ @NonNull IBiometricSysuiReceiver sysuiReceiver,
+ @NonNull KeyStore keystore,
+ @NonNull Random random,
+ @NonNull ClientDeathReceiver clientDeathReceiver,
+ @NonNull PreAuthInfo preAuthInfo,
+ @NonNull IBinder token,
+ long requestId,
+ long operationId,
+ int userId,
+ @NonNull IBiometricSensorReceiver sensorReceiver,
+ @NonNull IBiometricServiceReceiver clientReceiver,
+ @NonNull String opPackageName,
+ @NonNull PromptInfo promptInfo,
+ boolean debugEnabled,
+ @NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties,
+ @NonNull BiometricFrameworkStatsLogger logger) {
Slog.d(TAG, "Creating AuthSession with: " + preAuthInfo);
mContext = context;
mBiometricContext = biometricContext;
@@ -184,6 +211,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mDebugEnabled = debugEnabled;
mFingerprintSensorProperties = fingerprintSensorProperties;
mCancelled = false;
+ mBiometricFrameworkStatsLogger = logger;
try {
mClientReceiver.asBinder().linkToDeath(this, 0 /* flags */);
@@ -708,7 +736,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", Latency: " + latency);
}
- BiometricFrameworkStatsLogger.getInstance().authenticate(
+ mBiometricFrameworkStatsLogger.authenticate(
mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
isCrypto()),
statsModality(),
@@ -723,11 +751,17 @@ public final class AuthSession implements IBinder.DeathRecipient {
} else {
final long latency = System.currentTimeMillis() - mStartTimeMs;
- int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
- ? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
- : reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
- ? BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED
- : 0;
+ int error = 0;
+ switch(reason) {
+ case BiometricPrompt.DISMISSED_REASON_NEGATIVE:
+ error = BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON;
+ break;
+ case BiometricPrompt.DISMISSED_REASON_USER_CANCEL:
+ error = BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED;
+ break;
+ default:
+ }
+
if (DEBUG) {
Slog.v(TAG, "Dismissed! Modality: " + statsModality()
+ ", User: " + mUserId
@@ -739,17 +773,19 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", Latency: " + latency);
}
// Auth canceled
- BiometricFrameworkStatsLogger.getInstance().error(
- mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
- isCrypto()),
- statsModality(),
- BiometricsProtoEnums.ACTION_AUTHENTICATE,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
- mDebugEnabled,
- latency,
- error,
- 0 /* vendorCode */,
- mUserId);
+ if (error != 0) {
+ mBiometricFrameworkStatsLogger.error(
+ mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
+ isCrypto()),
+ statsModality(),
+ BiometricsProtoEnums.ACTION_AUTHENTICATE,
+ BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ mDebugEnabled,
+ latency,
+ error,
+ 0 /* vendorCode */,
+ mUserId);
+ }
}
}
diff --git a/services/core/java/com/android/server/biometrics/TEST_MAPPING b/services/core/java/com/android/server/biometrics/TEST_MAPPING
index daca00b40768..9e60ba8b5d87 100644
--- a/services/core/java/com/android/server/biometrics/TEST_MAPPING
+++ b/services/core/java/com/android/server/biometrics/TEST_MAPPING
@@ -6,24 +6,5 @@
{
"name": "CtsBiometricsHostTestCases"
}
- ],
- "ironwood-postsubmit": [
- {
- "name": "BiometricsE2eTests",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.platform.test.scenario.biometrics"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.FlakyTest"
- }
- ]
- }
- ]
+ ]
}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
index 21ade1bbbc4a..fc3d7c8114b0 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
@@ -156,7 +156,7 @@ public final class BiometricContextProvider implements BiometricContext {
@Override
public OperationContextExt updateContext(@NonNull OperationContextExt operationContext,
boolean isCryptoOperation) {
- return operationContext.update(this);
+ return operationContext.update(this, isCryptoOperation);
}
@Nullable
@@ -238,7 +238,7 @@ public final class BiometricContextProvider implements BiometricContext {
private void notifySubscribers() {
mSubscribers.forEach((context, consumer) -> {
- consumer.accept(context.update(this).toAidlContext());
+ consumer.accept(context.update(this, context.isCrypto()).toAidlContext());
});
}
diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
index 4d821e9819b4..4a10e8e428a3 100644
--- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
+++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
@@ -241,9 +241,10 @@ public class OperationContextExt {
}
/** Update this object with the latest values from the given context. */
- OperationContextExt update(@NonNull BiometricContext biometricContext) {
+ OperationContextExt update(@NonNull BiometricContext biometricContext, boolean isCrypto) {
mAidlContext.isAod = biometricContext.isAod();
mAidlContext.displayState = toAidlDisplayState(biometricContext.getDisplayState());
+ mAidlContext.isCrypto = isCrypto;
setFirstSessionId(biometricContext);
mIsDisplayOn = biometricContext.isDisplayOn();
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 05ca6e4554fb..6ac163121d8c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -266,8 +266,12 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions>
}
} else {
if (isBackgroundAuth) {
- Slog.e(TAG, "cancelling due to background auth");
- cancel();
+ Slog.e(TAG, "Sending cancel to client(Due to background auth)");
+ if (mTaskStackListener != null) {
+ mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+ }
+ sendCancelOnly(getListener());
+ mCallback.onClientFinished(this, false);
} else {
// Allow system-defined limit of number of attempts before giving up
if (mShouldUseLockoutTracker) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index b474cad962c3..aa5f9fa96875 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -32,6 +32,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.expresslog.Counter;
import com.android.server.biometrics.BiometricSchedulerProto;
import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
@@ -569,9 +570,10 @@ public class BiometricScheduler {
if (mCurrentOperation == null) {
return;
}
- final BiometricSchedulerOperation mOperation = mCurrentOperation;
+ final BiometricSchedulerOperation operation = mCurrentOperation;
mHandler.postDelayed(() -> {
- if (mOperation == mCurrentOperation) {
+ if (operation == mCurrentOperation) {
+ Counter.logIncrement("biometric.scheduler_watchdog_triggered_count");
clearScheduler();
}
}, 10000);
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
index a486d16189fa..694dfd28d0cc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -70,9 +70,11 @@ public class UserAwareBiometricScheduler extends BiometricScheduler {
// Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
// for that the queue will wait indefinitely until the field is cleared.
- if (clientMonitor instanceof StopUserClient<?> && !success) {
- Slog.w(getTag(),
- "StopUserClient failed(), is the HAL stuck? Clearing mStopUserClient");
+ if (clientMonitor instanceof StopUserClient<?>) {
+ if (!success) {
+ Slog.w(getTag(), "StopUserClient failed(), is the HAL stuck? "
+ + "Clearing mStopUserClient");
+ }
mStopUserClient = null;
}
if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index c2994a953f31..6f26e7b3e4b4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -415,6 +415,11 @@ public class FaceService extends SystemService {
}
}
}
+
+ @Override
+ public void onError(int error, int vendorCode) throws RemoteException {
+ receiver.onError(error, vendorCode);
+ }
};
// This effectively iterates through all sensors, but has to do so by finding all
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index ffbf4e12f2ae..2ad41c2a7a02 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -89,7 +89,7 @@ public class Sensor {
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
@NonNull private final Supplier<AidlSession> mLazySession;
- @Nullable private AidlSession mCurrentSession;
+ @Nullable AidlSession mCurrentSession;
@VisibleForTesting
public static class HalSessionCallback extends ISessionCallback.Stub {
@@ -486,7 +486,7 @@ public class Sensor {
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
- @NonNull BiometricContext biometricContext) {
+ @NonNull BiometricContext biometricContext, AidlSession session) {
mTag = tag;
mProvider = provider;
mContext = context;
@@ -549,6 +549,14 @@ public class Sensor {
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
}
+ Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
+ @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
+ @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+ @NonNull BiometricContext biometricContext) {
+ this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
+ biometricContext, null);
+ }
+
@NonNull Supplier<AidlSession> getLazySession() {
return mLazySession;
}
@@ -557,7 +565,7 @@ public class Sensor {
return mSensorProperties;
}
- @Nullable AidlSession getSessionForUser(int userId) {
+ @VisibleForTesting @Nullable AidlSession getSessionForUser(int userId) {
if (mCurrentSession != null && mCurrentSession.getUserId() == userId) {
return mCurrentSession;
} else {
@@ -641,6 +649,8 @@ public class Sensor {
BiometricsProtoEnums.MODALITY_FACE,
BiometricsProtoEnums.ISSUE_HAL_DEATH,
-1 /* sensorId */);
+ } else if (client != null) {
+ client.cancel();
}
mScheduler.recordCrashState();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index c0dde721b962..56b85ceb8e6b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -90,7 +90,7 @@ public class Sensor {
@NonNull private final LockoutCache mLockoutCache;
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
- @Nullable private AidlSession mCurrentSession;
+ @Nullable AidlSession mCurrentSession;
@NonNull private final Supplier<AidlSession> mLazySession;
@VisibleForTesting
@@ -439,7 +439,7 @@ public class Sensor {
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
- @NonNull BiometricContext biometricContext) {
+ @NonNull BiometricContext biometricContext, AidlSession session) {
mTag = tag;
mProvider = provider;
mContext = context;
@@ -501,6 +501,16 @@ public class Sensor {
});
mAuthenticatorIds = new HashMap<>();
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
+ mCurrentSession = session;
+ }
+
+ Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context,
+ @NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
+ @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+ @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
+ @NonNull BiometricContext biometricContext) {
+ this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
+ gestureAvailabilityDispatcher, biometricContext, null);
}
@NonNull Supplier<AidlSession> getLazySession() {
@@ -599,6 +609,8 @@ public class Sensor {
BiometricsProtoEnums.MODALITY_FINGERPRINT,
BiometricsProtoEnums.ISSUE_HAL_DEATH,
-1 /* sensorId */);
+ } else if (client != null) {
+ client.cancel();
}
mScheduler.recordCrashState();
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4208a12f91d4..e85eee817d29 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -309,6 +309,8 @@ public class Vpn {
*/
@VisibleForTesting
static final int DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC = 60;
+
+ private static final int PREFERRED_IKE_PROTOCOL_UNKNOWN = -1;
/**
* Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and
* {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets.
@@ -3643,11 +3645,11 @@ public class Vpn {
final int natKeepalive =
carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
- final int preferredIpPortocol =
- carrierConfig.getInt(KEY_PREFERRED_IKE_PROTOCOL_INT);
+ final int preferredIpProtocol = carrierConfig.getInt(
+ KEY_PREFERRED_IKE_PROTOCOL_INT, PREFERRED_IKE_PROTOCOL_UNKNOWN);
final String mccMnc = perSubTm.getSimOperator(subId);
final CarrierConfigInfo info =
- buildCarrierConfigInfo(mccMnc, natKeepalive, preferredIpPortocol);
+ buildCarrierConfigInfo(mccMnc, natKeepalive, preferredIpProtocol);
synchronized (Vpn.this) {
mCachedCarrierConfigInfoPerSubId.put(subId, info);
}
@@ -3828,10 +3830,27 @@ public class Vpn {
}, retryDelayMs, TimeUnit.MILLISECONDS);
}
+ private boolean significantCapsChange(@Nullable final NetworkCapabilities left,
+ @Nullable final NetworkCapabilities right) {
+ if (left == right) return false;
+ return null == left
+ || null == right
+ || !Arrays.equals(left.getTransportTypes(), right.getTransportTypes())
+ || !Arrays.equals(left.getCapabilities(), right.getCapabilities())
+ || !Arrays.equals(left.getEnterpriseIds(), right.getEnterpriseIds())
+ || !Objects.equals(left.getTransportInfo(), right.getTransportInfo())
+ || !Objects.equals(left.getAllowedUids(), right.getAllowedUids())
+ || !Objects.equals(left.getUnderlyingNetworks(), right.getUnderlyingNetworks())
+ || !Objects.equals(left.getNetworkSpecifier(), right.getNetworkSpecifier());
+ }
+
/** Called when the NetworkCapabilities of underlying network is changed */
public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
- mEventChanges.log("[UnderlyingNW] Cap changed from "
- + mUnderlyingNetworkCapabilities + " to " + nc);
+ if (significantCapsChange(mUnderlyingNetworkCapabilities, nc)) {
+ // TODO : make this log terser
+ mEventChanges.log("[UnderlyingNW] Cap changed from "
+ + mUnderlyingNetworkCapabilities + " to " + nc);
+ }
final NetworkCapabilities oldNc = mUnderlyingNetworkCapabilities;
mUnderlyingNetworkCapabilities = nc;
if (oldNc == null || !nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) {
@@ -4993,7 +5012,7 @@ public class Vpn {
* Retrieve the VpnProfileState for the profile provisioned by the given package.
*
* @return the VpnProfileState with current information, or null if there was no profile
- * provisioned by the given package.
+ * provisioned and started by the given package.
*/
@Nullable
public synchronized VpnProfileState getProvisionedVpnProfileState(
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 774087c63f0f..d647757442e0 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -223,11 +223,11 @@ public class AutomaticBrightnessController {
private final ShortTermModel mShortTermModel;
private final ShortTermModel mPausedShortTermModel;
- // Controls High Brightness Mode.
- private HighBrightnessModeController mHbmController;
+ // Controls Brightness range (including High Brightness Mode).
+ private final BrightnessRangeController mBrightnessRangeController;
// Throttles (caps) maximum allowed brightness
- private BrightnessThrottler mBrightnessThrottler;
+ private final BrightnessThrottler mBrightnessThrottler;
private boolean mIsBrightnessThrottled;
// Context-sensitive brightness configurations require keeping track of the foreground app's
@@ -257,7 +257,8 @@ public class AutomaticBrightnessController {
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+ BrightnessRangeController brightnessModeController,
+ BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) {
this(new Injector(), callbacks, looper, sensorManager, lightSensor,
@@ -267,7 +268,7 @@ public class AutomaticBrightnessController {
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context,
- hbmController, brightnessThrottler, idleModeBrightnessMapper,
+ brightnessModeController, brightnessThrottler, idleModeBrightnessMapper,
ambientLightHorizonShort, ambientLightHorizonLong, userLux, userBrightness
);
}
@@ -283,7 +284,8 @@ public class AutomaticBrightnessController {
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+ BrightnessRangeController brightnessModeController,
+ BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) {
mInjector = injector;
@@ -326,18 +328,15 @@ public class AutomaticBrightnessController {
mPendingForegroundAppPackageName = null;
mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
- mHbmController = hbmController;
+ mBrightnessRangeController = brightnessModeController;
mBrightnessThrottler = brightnessThrottler;
mInteractiveModeBrightnessMapper = interactiveModeBrightnessMapper;
mIdleModeBrightnessMapper = idleModeBrightnessMapper;
// Initialize to active (normal) screen brightness mode
switchToInteractiveScreenBrightnessMode();
- if (userLux != BrightnessMappingStrategy.NO_USER_LUX
- && userBrightness != BrightnessMappingStrategy.NO_USER_BRIGHTNESS) {
- // Use the given short-term model
- setScreenBrightnessByUser(userLux, userBrightness);
- }
+ // Use the given short-term model
+ setScreenBrightnessByUser(userLux, userBrightness);
}
/**
@@ -520,6 +519,10 @@ public class AutomaticBrightnessController {
}
private boolean setScreenBrightnessByUser(float lux, float brightness) {
+ if (lux == BrightnessMappingStrategy.NO_USER_LUX
+ || brightness == BrightnessMappingStrategy.NO_USER_BRIGHTNESS) {
+ return false;
+ }
mCurrentBrightnessMapper.addUserDataPoint(lux, brightness);
mShortTermModel.setUserBrightness(lux, brightness);
return true;
@@ -606,10 +609,11 @@ public class AutomaticBrightnessController {
pw.println();
pw.println(" mInteractiveMapper=");
- mInteractiveModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax());
+ mInteractiveModeBrightnessMapper.dump(pw,
+ mBrightnessRangeController.getNormalBrightnessMax());
if (mIdleModeBrightnessMapper != null) {
pw.println(" mIdleMapper=");
- mIdleModeBrightnessMapper.dump(pw, mHbmController.getNormalBrightnessMax());
+ mIdleModeBrightnessMapper.dump(pw, mBrightnessRangeController.getNormalBrightnessMax());
}
pw.println();
@@ -735,7 +739,7 @@ public class AutomaticBrightnessController {
mAmbientDarkeningThreshold =
mAmbientBrightnessThresholds.getDarkeningThreshold(lux);
}
- mHbmController.onAmbientLuxChange(mAmbientLux);
+ mBrightnessRangeController.onAmbientLuxChange(mAmbientLux);
// If the short term model was invalidated and the change is drastic enough, reset it.
@@ -975,9 +979,9 @@ public class AutomaticBrightnessController {
// Clamps values with float range [0.0-1.0]
private float clampScreenBrightness(float value) {
- final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(),
+ final float minBrightness = Math.min(mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap());
- final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(),
+ final float maxBrightness = Math.min(mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap());
return MathUtils.constrain(value, minBrightness, maxBrightness);
}
@@ -1234,14 +1238,14 @@ public class AutomaticBrightnessController {
// light.
// The anchor determines what were the light levels when the user has set their preference,
// and we use a relative threshold to determine when to revert to the OEM curve.
- private float mAnchor = -1f;
- private float mBrightness;
- private boolean mIsValid = true;
+ private float mAnchor = BrightnessMappingStrategy.NO_USER_LUX;
+ private float mBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ private boolean mIsValid = false;
private void reset() {
- mAnchor = -1f;
- mBrightness = -1f;
- mIsValid = true;
+ mAnchor = BrightnessMappingStrategy.NO_USER_LUX;
+ mBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ mIsValid = false;
}
private void invalidate() {
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
new file mode 100644
index 000000000000..12813c82bfff
--- /dev/null
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.hardware.display.BrightnessInfo;
+import android.os.IBinder;
+
+import java.io.PrintWriter;
+
+class BrightnessRangeController {
+
+ private static final boolean NBM_FEATURE_FLAG = false;
+
+ private final HighBrightnessModeController mHbmController;
+ private final NormalBrightnessModeController mNormalBrightnessModeController =
+ new NormalBrightnessModeController();
+
+ private final Runnable mModeChangeCallback;
+
+ BrightnessRangeController(HighBrightnessModeController hbmController,
+ Runnable modeChangeCallback) {
+ mHbmController = hbmController;
+ mModeChangeCallback = modeChangeCallback;
+ }
+
+
+ void dump(PrintWriter pw) {
+ mHbmController.dump(pw);
+ }
+
+ void onAmbientLuxChange(float ambientLux) {
+ if (NBM_FEATURE_FLAG) {
+ boolean nbmTransitionChanged = mNormalBrightnessModeController.onAmbientLuxChange(
+ ambientLux);
+ int previousHbm = mHbmController.getHighBrightnessMode();
+ mHbmController.onAmbientLuxChange(ambientLux);
+ int nextHbm = mHbmController.getHighBrightnessMode();
+ // if hbm changed - callback was triggered in mHbmController.onAmbientLuxChange
+ // if nbm transition not changed - no need to trigger callback
+ if (previousHbm == nextHbm && nbmTransitionChanged) {
+ mModeChangeCallback.run();
+ }
+ } else {
+ mHbmController.onAmbientLuxChange(ambientLux);
+ }
+ }
+
+ float getNormalBrightnessMax() {
+ return mHbmController.getNormalBrightnessMax();
+ }
+
+ void loadFromConfig(HighBrightnessModeMetadata hbmMetadata, IBinder token,
+ DisplayDeviceInfo info, DisplayDeviceConfig displayDeviceConfig) {
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
+ mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
+ displayDeviceConfig.getHighBrightnessModeData(),
+ displayDeviceConfig::getHdrBrightnessFromSdr);
+ }
+
+ void stop() {
+ mHbmController.stop();
+ }
+
+ void setAutoBrightnessEnabled(int state) {
+ mHbmController.setAutoBrightnessEnabled(state);
+ }
+
+ void onBrightnessChanged(float brightness, float unthrottledBrightness,
+ @BrightnessInfo.BrightnessMaxReason int throttlingReason) {
+ mHbmController.onBrightnessChanged(brightness, unthrottledBrightness, throttlingReason);
+ }
+
+ float getCurrentBrightnessMin() {
+ return mHbmController.getCurrentBrightnessMin();
+ }
+
+
+ float getCurrentBrightnessMax() {
+ if (NBM_FEATURE_FLAG && mHbmController.getHighBrightnessMode()
+ == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF) {
+ return Math.min(mHbmController.getCurrentBrightnessMax(),
+ mNormalBrightnessModeController.getCurrentBrightnessMax());
+ }
+ return mHbmController.getCurrentBrightnessMax();
+ }
+
+ int getHighBrightnessMode() {
+ return mHbmController.getHighBrightnessMode();
+ }
+
+ float getHdrBrightnessValue() {
+ return mHbmController.getHdrBrightnessValue();
+ }
+
+ float getTransitionPoint() {
+ return mHbmController.getTransitionPoint();
+ }
+}
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index de42370e6d84..651828b6b9e2 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -40,6 +40,7 @@ public class BrightnessSetting {
private final LogicalDisplay mLogicalDisplay;
+ private int mUserSerial;
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
@@ -56,13 +57,15 @@ public class BrightnessSetting {
@GuardedBy("mSyncRoot")
private float mBrightness;
- BrightnessSetting(@NonNull PersistentDataStore persistentDataStore,
+ BrightnessSetting(int userSerial,
+ @NonNull PersistentDataStore persistentDataStore,
@NonNull LogicalDisplay logicalDisplay,
DisplayManagerService.SyncRoot syncRoot) {
mPersistentDataStore = persistentDataStore;
mLogicalDisplay = logicalDisplay;
+ mUserSerial = userSerial;
mBrightness = mPersistentDataStore.getBrightness(
- mLogicalDisplay.getPrimaryDisplayDeviceLocked());
+ mLogicalDisplay.getPrimaryDisplayDeviceLocked(), userSerial);
mSyncRoot = syncRoot;
}
@@ -96,8 +99,13 @@ public class BrightnessSetting {
mListeners.remove(l);
}
+ /** Sets the user serial for the brightness setting */
+ public void setUserSerial(int userSerial) {
+ mUserSerial = userSerial;
+ }
+
/**
- * Sets the brigtness and broadcasts the change to the listeners.
+ * Sets the brightness and broadcasts the change to the listeners.
* @param brightness The value to which the brightness is to be set.
*/
public void setBrightness(float brightness) {
@@ -112,7 +120,8 @@ public class BrightnessSetting {
// changed.
if (brightness != mBrightness) {
mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
- brightness);
+ brightness, mUserSerial
+ );
}
mBrightness = brightness;
int toSend = Float.floatToIntBits(mBrightness);
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index e8c65efeb5cd..d55065064871 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -796,6 +796,7 @@ public class BrightnessTracker {
pw.print(", isUserSetBrightness=" + events[i].isUserSetBrightness);
pw.print(", powerBrightnessFactor=" + events[i].powerBrightnessFactor);
pw.print(", isDefaultBrightnessConfig=" + events[i].isDefaultBrightnessConfig);
+ pw.print(", recent lux values=");
pw.print(" {");
for (int j = 0; j < events[i].luxValues.length; ++j){
if (j != 0) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index ca482dc41ce5..7a797dd2250c 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -889,6 +889,13 @@ public class DisplayDeviceConfig {
}
/**
+ * @return true if there is sdrHdrRatioMap, false otherwise.
+ */
+ public boolean hasSdrToHdrRatioSpline() {
+ return mSdrToHdrRatioSpline != null;
+ }
+
+ /**
* Calculate the HDR brightness for the specified SDR brightenss, restricted by the
* maxDesiredHdrSdrRatio (the ratio between the HDR luminance and SDR luminance)
*
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 38445295b0f1..c559ed867dd3 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -238,6 +238,7 @@ public final class DisplayManagerService extends SystemService {
private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATIONS = 6;
private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;
+ private static final int MSG_RECEIVED_DEVICE_STATE = 9;
private static final int[] EMPTY_ARRAY = new int[0];
private static final HdrConversionMode HDR_CONVERSION_MODE_UNSUPPORTED = new HdrConversionMode(
HDR_CONVERSION_UNSUPPORTED);
@@ -652,6 +653,12 @@ public final class DisplayManagerService extends SystemService {
logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(),
userSerial);
dpc.setBrightnessConfiguration(config, /* shouldResetShortTermModel= */ true);
+ // change the brightness value according to the selected user.
+ final DisplayDevice device = logicalDisplay.getPrimaryDisplayDeviceLocked();
+ if (device != null) {
+ dpc.setBrightness(
+ mPersistentDataStore.getBrightness(device, userSerial), userSerial);
+ }
}
dpc.onSwitchUser(newUserId);
});
@@ -3134,8 +3141,9 @@ public final class DisplayManagerService extends SystemService {
mBrightnessTracker = new BrightnessTracker(mContext, null);
}
- final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore,
- display, mSyncRoot);
+ final int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId());
+ final BrightnessSetting brightnessSetting = new BrightnessSetting(userSerial,
+ mPersistentDataStore, display, mSyncRoot);
final DisplayPowerControllerInterface displayPowerController;
// If display is internal and has a HighBrightnessModeMetadata mapping, use that.
@@ -3213,6 +3221,10 @@ public final class DisplayManagerService extends SystemService {
mWindowManagerInternal.requestTraversalFromDisplayManager();
break;
+ case MSG_RECEIVED_DEVICE_STATE:
+ mWindowManagerInternal.onDisplayManagerReceivedDeviceState(msg.arg1);
+ break;
+
case MSG_UPDATE_VIEWPORT: {
final boolean changed;
synchronized (mSyncRoot) {
@@ -4680,6 +4692,14 @@ public final class DisplayManagerService extends SystemService {
public void onStateChanged(int deviceState) {
boolean isDeviceStateOverrideActive = deviceState != mBaseState;
synchronized (mSyncRoot) {
+ // Notify WindowManager that we are about to handle new device state, this should
+ // be sent before any work related to the device state in DisplayManager, so
+ // WindowManager could do implement that depends on the device state and display
+ // changes (serializes device state update and display change events)
+ Message msg = mHandler.obtainMessage(MSG_RECEIVED_DEVICE_STATE);
+ msg.arg1 = deviceState;
+ mHandler.sendMessage(msg);
+
mLogicalDisplayMapper
.setDeviceStateLocked(deviceState, isDeviceStateOverrideActive);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 9d31572c7d76..7d8bde9feabf 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -445,7 +445,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final ColorDisplayServiceInternal mCdsi;
private float[] mNitsRange;
- private final HighBrightnessModeController mHbmController;
+ private final BrightnessRangeController mBrightnessRangeController;
private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler;
@@ -654,8 +654,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
loadBrightnessRampRates();
mSkipScreenOnBrightnessRamp = resources.getBoolean(
com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);
+ Runnable modeChangeCallback = () -> {
+ sendUpdatePowerState();
+ postBrightnessChangeRunnable();
+ // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
+ if (mAutomaticBrightnessController != null) {
+ mAutomaticBrightnessController.update();
+ }
+ };
- mHbmController = createHbmControllerLocked();
+ HighBrightnessModeController hbmController = createHbmControllerLocked(modeChangeCallback);
+
+ mBrightnessRangeController = new BrightnessRangeController(hbmController,
+ modeChangeCallback);
mBrightnessThrottler = createBrightnessThrottlerLocked();
@@ -802,7 +813,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
- mHbmController.onAmbientLuxChange(ambientLux);
+ mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) {
mBrightnessToFollow = leadDisplayBrightness;
} else {
@@ -1039,17 +1050,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
- mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
- mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
- mDisplayDeviceConfig.getHighBrightnessModeData(),
- new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
- @Override
- public float getHdrBrightnessFromSdr(
- float sdrBrightness, float maxDesiredHdrSdrRatio) {
- return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
- sdrBrightness, maxDesiredHdrSdrRatio);
- }
- });
+ mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
@@ -1264,7 +1265,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
- mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
+ mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
@@ -1364,7 +1365,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
private void cleanupHandlerThreadAfterStop() {
setProximitySensorEnabled(false);
- mHbmController.stop();
+ mBrightnessRangeController.stop();
mBrightnessThrottler.stop();
mHandler.removeCallbacksAndMessages(null);
@@ -1647,7 +1648,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
}
- mHbmController.setAutoBrightnessEnabled(mUseAutoBrightness
+ mBrightnessRangeController.setAutoBrightnessEnabled(mUseAutoBrightness
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
@@ -1820,7 +1821,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// here instead of having HbmController listen to the brightness setting because certain
// brightness sources (such as an app override) are not saved to the setting, but should be
// reflected in HBM calculations.
- mHbmController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
+ mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
mBrightnessThrottler.getBrightnessMaxReason());
// Animate the screen brightness when the screen is on or dozing.
@@ -1874,13 +1875,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
float sdrAnimateValue = animateValue;
// TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
// done in HighBrightnessModeController.
- if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
+ if (mBrightnessRangeController.getHighBrightnessMode()
+ == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
== 0) {
// We want to scale HDR brightness level with the SDR level, we also need to restore
// SDR brightness immediately when entering dim or low power mode.
- animateValue = mHbmController.getHdrBrightnessValue();
+ animateValue = mBrightnessRangeController.getHdrBrightnessValue();
}
final float currentBrightness = mPowerState.getScreenBrightness();
@@ -1942,8 +1944,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mTempBrightnessEvent.setBrightness(brightnessState);
mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
mTempBrightnessEvent.setReason(mBrightnessReason);
- mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax());
- mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode());
+ mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
+ mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
| (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
| (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
@@ -2104,9 +2106,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) {
- final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(),
+ final float minBrightness = Math.min(
+ mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap());
- final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(),
+ final float maxBrightness = Math.min(
+ mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap());
boolean changed = false;
@@ -2124,10 +2128,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
maxBrightness);
changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
- mHbmController.getHighBrightnessMode());
+ mBrightnessRangeController.getHighBrightnessMode());
changed |=
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
- mHbmController.getTransitionPoint());
+ mBrightnessRangeController.getTransitionPoint());
changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
mBrightnessThrottler.getBrightnessMaxReason());
@@ -2140,7 +2144,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mHandler.post(mOnBrightnessChangeRunnable);
}
- private HighBrightnessModeController createHbmControllerLocked() {
+ private HighBrightnessModeController createHbmControllerLocked(
+ Runnable modeChangeCallback) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
final IBinder displayToken =
@@ -2159,15 +2164,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
sdrBrightness, maxDesiredHdrSdrRatio);
}
- },
- () -> {
- sendUpdatePowerState();
- postBrightnessChangeRunnable();
- // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.update();
- }
- }, mHighBrightnessModeMetadata, mContext);
+ }, modeChangeCallback, mHighBrightnessModeMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
@@ -2328,8 +2325,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (Float.isNaN(value)) {
value = PowerManager.BRIGHTNESS_MIN;
}
- return MathUtils.constrain(value,
- mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
+ return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
+ mBrightnessRangeController.getCurrentBrightnessMax());
}
// Checks whether the brightness is within the valid brightness range, not including off.
@@ -2667,9 +2664,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
@Override
- public void setBrightness(float brightnessValue) {
+ public void setBrightness(float brightnessValue, int userSerial) {
// Update the setting, which will eventually call back into DPC to have us actually update
// the display with the new value.
+ mBrightnessSetting.setUserSerial(userSerial);
mBrightnessSetting.setBrightness(brightnessValue);
if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
float nits = convertToNits(brightnessValue);
@@ -3003,8 +3001,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mScreenOffBrightnessSensorController.dump(pw);
}
- if (mHbmController != null) {
- mHbmController.dump(pw);
+ if (mBrightnessRangeController != null) {
+ mBrightnessRangeController.dump(pw);
}
if (mBrightnessThrottler != null) {
@@ -3471,7 +3469,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+ BrightnessRangeController brightnessRangeController,
+ BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) {
return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
@@ -3480,9 +3479,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
brighteningLightDebounceConfig, darkeningLightDebounceConfig,
resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
- screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler,
- idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong,
- userLux, userBrightness);
+ screenBrightnessThresholdsIdle, context, brightnessRangeController,
+ brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort,
+ ambientLightHorizonLong, userLux, userBrightness);
}
BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 167414188180..040ceccbc7c9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -157,6 +157,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
private static final int RINGBUFFER_MAX = 100;
+ private static final int RINGBUFFER_RBC_MAX = 20;
private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
@@ -375,8 +376,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private final ColorDisplayServiceInternal mCdsi;
private float[] mNitsRange;
- private final HighBrightnessModeController mHbmController;
- private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
+ private final BrightnessRangeController mBrightnessRangeController;
private final BrightnessThrottler mBrightnessThrottler;
@@ -390,6 +390,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// Keeps a record of brightness changes for dumpsys.
private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer;
+ // Keeps a record of rbc changes for dumpsys.
+ private final RingBuffer<BrightnessEvent> mRbcEventRingBuffer =
+ new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_RBC_MAX);
+
// Controls and tracks all the wakelocks that are acquired/released by the system. Also acts as
// a medium of communication between this class and the PowerManagerService.
private final WakelockController mWakelockController;
@@ -484,7 +488,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
() -> updatePowerState(), mDisplayId, mSensorManager);
- mHighBrightnessModeMetadata = hbmMetadata;
mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(context, mDisplayId);
mTag = "DisplayPowerController2[" + mDisplayId + "]";
@@ -527,9 +530,22 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mSkipScreenOnBrightnessRamp = resources.getBoolean(
R.bool.config_skipScreenOnBrightnessRamp);
- mHbmController = createHbmControllerLocked();
+ Runnable modeChangeCallback = () -> {
+ sendUpdatePowerState();
+ postBrightnessChangeRunnable();
+ // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
+ if (mAutomaticBrightnessController != null) {
+ mAutomaticBrightnessController.update();
+ }
+ };
+ HighBrightnessModeController hbmController = createHbmControllerLocked(hbmMetadata,
+ modeChangeCallback);
mBrightnessThrottler = createBrightnessThrottlerLocked();
+
+ mBrightnessRangeController = new BrightnessRangeController(hbmController,
+ modeChangeCallback);
+
mDisplayBrightnessController =
new DisplayBrightnessController(context, null,
mDisplayId, mLogicalDisplay.getDisplayInfoLocked().brightnessDefault,
@@ -843,17 +859,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
- mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
- mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
- mDisplayDeviceConfig.getHighBrightnessModeData(),
- new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
- @Override
- public float getHdrBrightnessFromSdr(
- float sdrBrightness, float maxDesiredHdrSdrRatio) {
- return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
- sdrBrightness, maxDesiredHdrSdrRatio);
- }
- });
+
+ mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig);
mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(),
mThermalBrightnessThrottlingDataId, mUniqueDisplayId);
@@ -1071,7 +1078,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
ambientBrightnessThresholds, screenBrightnessThresholds,
ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext,
- mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
+ mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
mDisplayBrightnessController.setAutomaticBrightnessController(
@@ -1175,7 +1182,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
private void cleanupHandlerThreadAfterStop() {
mDisplayPowerProximityStateController.cleanup();
- mHbmController.stop();
+ mBrightnessRangeController.stop();
mBrightnessThrottler.stop();
mHandler.removeCallbacksAndMessages(null);
@@ -1290,7 +1297,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
&& (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged()
|| userSetBrightnessChanged);
- mHbmController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy
+ mBrightnessRangeController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy
.shouldUseAutoBrightness()
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
@@ -1447,7 +1454,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
// here instead of having HbmController listen to the brightness setting because certain
// brightness sources (such as an app override) are not saved to the setting, but should be
// reflected in HBM calculations.
- mHbmController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
+ mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
mBrightnessThrottler.getBrightnessMaxReason());
// Animate the screen brightness when the screen is on or dozing.
@@ -1504,13 +1511,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
float sdrAnimateValue = animateValue;
// TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
// done in HighBrightnessModeController.
- if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
+ if (mBrightnessRangeController.getHighBrightnessMode()
+ == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
&& (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
== 0) {
// We want to scale HDR brightness level with the SDR level, we also need to restore
// SDR brightness immediately when entering dim or low power mode.
- animateValue = mHbmController.getHdrBrightnessValue();
+ animateValue = mBrightnessRangeController.getHdrBrightnessValue();
}
final float currentBrightness = mPowerState.getScreenBrightness();
@@ -1574,8 +1582,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mTempBrightnessEvent.setBrightness(brightnessState);
mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
mTempBrightnessEvent.setReason(mBrightnessReason);
- mTempBrightnessEvent.setHbmMax(mHbmController.getCurrentBrightnessMax());
- mTempBrightnessEvent.setHbmMode(mHbmController.getHighBrightnessMode());
+ mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
+ mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
mTempBrightnessEvent.setFlags(mTempBrightnessEvent.getFlags()
| (mIsRbcActive ? BrightnessEvent.FLAG_RBC : 0)
| (mPowerRequest.lowPowerMode ? BrightnessEvent.FLAG_LOW_POWER_MODE : 0));
@@ -1593,6 +1601,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
&& mLastBrightnessEvent.getReason().getReason()
== BrightnessReason.REASON_TEMPORARY;
+ // Purely for dumpsys;
+ final boolean isRbcEvent =
+ mLastBrightnessEvent.isRbcEnabled() != mTempBrightnessEvent.isRbcEnabled();
+
if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
|| brightnessAdjustmentFlags != 0) {
mTempBrightnessEvent.setInitialBrightness(mLastBrightnessEvent.getBrightness());
@@ -1612,6 +1624,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
if (mBrightnessEventRingBuffer != null) {
mBrightnessEventRingBuffer.append(newEvent);
}
+ if (isRbcEvent) {
+ mRbcEventRingBuffer.append(newEvent);
+ }
+
}
// Update display white-balance.
@@ -1737,9 +1753,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) {
- final float minBrightness = Math.min(mHbmController.getCurrentBrightnessMin(),
+ final float minBrightness = Math.min(
+ mBrightnessRangeController.getCurrentBrightnessMin(),
mBrightnessThrottler.getBrightnessCap());
- final float maxBrightness = Math.min(mHbmController.getCurrentBrightnessMax(),
+ final float maxBrightness = Math.min(
+ mBrightnessRangeController.getCurrentBrightnessMax(),
mBrightnessThrottler.getBrightnessCap());
boolean changed = false;
@@ -1757,10 +1775,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
maxBrightness);
changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
- mHbmController.getHighBrightnessMode());
+ mBrightnessRangeController.getHighBrightnessMode());
changed |=
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
- mHbmController.getTransitionPoint());
+ mBrightnessRangeController.getTransitionPoint());
changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
mBrightnessThrottler.getBrightnessMaxReason());
@@ -1773,7 +1791,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mHandler.post(mOnBrightnessChangeRunnable);
}
- private HighBrightnessModeController createHbmControllerLocked() {
+ private HighBrightnessModeController createHbmControllerLocked(
+ HighBrightnessModeMetadata hbmMetadata, Runnable modeChangeCallback) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
final IBinder displayToken =
@@ -1785,22 +1804,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
return new HighBrightnessModeController(mHandler, info.width, info.height, displayToken,
displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
- new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
- @Override
- public float getHdrBrightnessFromSdr(
- float sdrBrightness, float maxDesiredHdrSdrRatio) {
- return mDisplayDeviceConfig.getHdrBrightnessFromSdr(
- sdrBrightness, maxDesiredHdrSdrRatio);
- }
- },
- () -> {
- sendUpdatePowerState();
- postBrightnessChangeRunnable();
- // TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
- if (mAutomaticBrightnessController != null) {
- mAutomaticBrightnessController.update();
- }
- }, mHighBrightnessModeMetadata, mContext);
+ (sdrBrightness, maxDesiredHdrSdrRatio) ->
+ mDisplayDeviceConfig.getHdrBrightnessFromSdr(sdrBrightness,
+ maxDesiredHdrSdrRatio), modeChangeCallback, hbmMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
@@ -1947,8 +1953,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
if (Float.isNaN(value)) {
value = PowerManager.BRIGHTNESS_MIN;
}
- return MathUtils.constrain(value,
- mHbmController.getCurrentBrightnessMin(), mHbmController.getCurrentBrightnessMax());
+ return MathUtils.constrain(value, mBrightnessRangeController.getCurrentBrightnessMin(),
+ mBrightnessRangeController.getCurrentBrightnessMax());
}
private void animateScreenBrightness(float target, float sdrTarget, float rate) {
@@ -2166,8 +2172,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
@Override
- public void setBrightness(float brightnessValue) {
- mDisplayBrightnessController.setBrightness(brightnessValue);
+ public void setBrightness(float brightnessValue, int userSerial) {
+ mDisplayBrightnessController.setBrightness(brightnessValue, userSerial);
}
@Override
@@ -2182,7 +2188,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
- mHbmController.onAmbientLuxChange(ambientLux);
+ mBrightnessRangeController.onAmbientLuxChange(ambientLux);
if (nits < 0) {
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
} else {
@@ -2359,8 +2365,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
dumpBrightnessEvents(pw);
}
- if (mHbmController != null) {
- mHbmController.dump(pw);
+ dumpRbcEvents(pw);
+
+ if (mBrightnessRangeController != null) {
+ mBrightnessRangeController.dump(pw);
}
if (mBrightnessThrottler != null) {
@@ -2431,6 +2439,20 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
}
+ private void dumpRbcEvents(PrintWriter pw) {
+ int size = mRbcEventRingBuffer.size();
+ if (size < 1) {
+ pw.println("No Reduce Bright Colors Adjustments");
+ return;
+ }
+
+ pw.println("Reduce Bright Colors Adjustments Last " + size + " Events: ");
+ BrightnessEvent[] eventArray = mRbcEventRingBuffer.toArray();
+ for (int i = 0; i < mRbcEventRingBuffer.size(); i++) {
+ pw.println(" " + eventArray[i]);
+ }
+ }
+
private void noteScreenState(int screenState) {
// Log screen state change with display id
@@ -2811,7 +2833,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+ BrightnessRangeController brightnessModeController,
+ BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
int ambientLightHorizonLong, float userLux, float userBrightness) {
return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
@@ -2820,9 +2843,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
brighteningLightDebounceConfig, darkeningLightDebounceConfig,
resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
- screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler,
- idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong,
- userLux, userBrightness);
+ screenBrightnessThresholdsIdle, context, brightnessModeController,
+ brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort,
+ ambientLightHorizonLong, userLux, userBrightness);
}
BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
index 73edb970ff95..5fbbcbd2959f 100644
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
@@ -29,7 +29,7 @@ import java.io.PrintWriter;
* An interface to manage the display's power state and brightness
*/
public interface DisplayPowerControllerInterface {
-
+ int DEFAULT_USER_SERIAL = -1;
/**
* Notified when the display is changed.
*
@@ -98,7 +98,17 @@ public interface DisplayPowerControllerInterface {
* Set the screen brightness of the associated display
* @param brightness The value to which the brightness is to be set
*/
- void setBrightness(float brightness);
+ default void setBrightness(float brightness) {
+ setBrightness(brightness, DEFAULT_USER_SERIAL);
+ }
+
+ /**
+ * Set the screen brightness of the associated display
+ * @param brightness The value to which the brightness is to be set
+ * @param userSerial The user for which the brightness value is to be set. Use userSerial = -1,
+ * if brightness needs to be updated for the current user.
+ */
+ void setBrightness(float brightness, int userSerial);
/**
* Checks if the proximity sensor is available
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 79984c9b5355..7701bc6271ae 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -701,11 +701,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
maxDisplayMode == null ? mInfo.width : maxDisplayMode.getPhysicalWidth();
final int maxHeight =
maxDisplayMode == null ? mInfo.height : maxDisplayMode.getPhysicalHeight();
- mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
- mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
- mInfo.roundedCorners = RoundedCorners.fromResources(
- res, mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
+ // We cannot determine cutouts and rounded corners of external displays.
+ if (mStaticDisplayInfo.isInternal) {
+ mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
+ mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
+ mInfo.roundedCorners = RoundedCorners.fromResources(
+ res, mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
+ }
+
mInfo.installOrientation = mStaticDisplayInfo.installOrientation;
mInfo.displayShape = DisplayShape.fromResources(
@@ -888,7 +892,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
BrightnessSynchronizer.brightnessFloatToInt(
sdrBrightnessState));
- handleHdrSdrNitsChanged(nits, sdrNits);
+ if (getDisplayDeviceConfig().hasSdrToHdrRatioSpline()) {
+ handleHdrSdrNitsChanged(nits, sdrNits);
+ }
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
diff --git a/services/core/java/com/android/server/display/NormalBrightnessModeController.java b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
new file mode 100644
index 000000000000..91e4a9e407db
--- /dev/null
+++ b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.os.PowerManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class NormalBrightnessModeController {
+ private Map<Float, Float> mTransitionPoints = new HashMap<>();
+
+ // brightness limit in normal brightness mode, based on ambient lux.
+ private float mVirtualTransitionPoint = PowerManager.BRIGHTNESS_MAX;
+
+ boolean onAmbientLuxChange(float ambientLux) {
+ float currentAmbientBoundary = Float.MAX_VALUE;
+ float currentTransitionPoint = PowerManager.BRIGHTNESS_MAX;
+ for (Map.Entry<Float, Float> transitionPoint: mTransitionPoints.entrySet()) {
+ float ambientBoundary = transitionPoint.getKey();
+ // find ambient lux upper boundary closest to current ambient lux
+ if (ambientBoundary > ambientLux && ambientBoundary < currentAmbientBoundary) {
+ currentTransitionPoint = transitionPoint.getValue();
+ currentAmbientBoundary = ambientBoundary;
+ }
+ }
+ if (mVirtualTransitionPoint != currentTransitionPoint) {
+ mVirtualTransitionPoint = currentTransitionPoint;
+ return true;
+ }
+ return false;
+ }
+
+ float getCurrentBrightnessMax() {
+ return mVirtualTransitionPoint;
+ }
+}
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 6d6ed726161b..2d7792d01c53 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -133,6 +133,7 @@ final class PersistentDataStore {
private static final String TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY =
"brightness-nits-for-default-display";
+ public static final int DEFAULT_USER_ID = -1;
// Remembered Wifi display devices.
private ArrayList<WifiDisplay> mRememberedWifiDisplays = new ArrayList<WifiDisplay>();
@@ -294,7 +295,7 @@ final class PersistentDataStore {
return false;
}
- public float getBrightness(DisplayDevice device) {
+ public float getBrightness(DisplayDevice device, int userSerial) {
if (device == null || !device.hasStableUniqueId()) {
return Float.NaN;
}
@@ -302,10 +303,10 @@ final class PersistentDataStore {
if (state == null) {
return Float.NaN;
}
- return state.getBrightness();
+ return state.getBrightness(userSerial);
}
- public boolean setBrightness(DisplayDevice displayDevice, float brightness) {
+ public boolean setBrightness(DisplayDevice displayDevice, float brightness, int userSerial) {
if (displayDevice == null || !displayDevice.hasStableUniqueId()) {
return false;
}
@@ -314,7 +315,7 @@ final class PersistentDataStore {
return false;
}
final DisplayState state = getDisplayState(displayDeviceUniqueId, true);
- if (state.setBrightness(brightness)) {
+ if (state.setBrightness(brightness, userSerial)) {
setDirty();
return true;
}
@@ -611,6 +612,7 @@ final class PersistentDataStore {
state.saveToXml(serializer);
serializer.endTag(null, TAG_DISPLAY);
}
+
serializer.endTag(null, TAG_DISPLAY_STATES);
serializer.startTag(null, TAG_STABLE_DEVICE_VALUES);
mStableDeviceValues.saveToXml(serializer);
@@ -649,7 +651,8 @@ final class PersistentDataStore {
private static final class DisplayState {
private int mColorMode;
- private float mBrightness = Float.NaN;
+
+ private SparseArray<Float> mPerUserBrightness = new SparseArray<>();
private int mWidth;
private int mHeight;
private float mRefreshRate;
@@ -670,16 +673,25 @@ final class PersistentDataStore {
return mColorMode;
}
- public boolean setBrightness(float brightness) {
- if (brightness == mBrightness) {
+ public boolean setBrightness(float brightness, int userSerial) {
+ // Remove the default user brightness, before setting a new user-specific value.
+ // This is a one-time operation, required to restructure the config after user-specific
+ // brightness was introduced.
+ mPerUserBrightness.remove(DEFAULT_USER_ID);
+
+ if (getBrightness(userSerial) == brightness) {
return false;
}
- mBrightness = brightness;
+ mPerUserBrightness.set(userSerial, brightness);
return true;
}
- public float getBrightness() {
- return mBrightness;
+ public float getBrightness(int userSerial) {
+ float brightness = mPerUserBrightness.get(userSerial, Float.NaN);
+ if (Float.isNaN(brightness)) {
+ brightness = mPerUserBrightness.get(DEFAULT_USER_ID, Float.NaN);
+ }
+ return brightness;
}
public boolean setBrightnessConfiguration(BrightnessConfiguration configuration,
@@ -729,12 +741,7 @@ final class PersistentDataStore {
mColorMode = Integer.parseInt(value);
break;
case TAG_BRIGHTNESS_VALUE:
- String brightness = parser.nextText();
- try {
- mBrightness = Float.parseFloat(brightness);
- } catch (NumberFormatException e) {
- mBrightness = Float.NaN;
- }
+ loadBrightnessFromXml(parser);
break;
case TAG_BRIGHTNESS_CONFIGURATIONS:
mDisplayBrightnessConfigurations.loadFromXml(parser);
@@ -760,11 +767,12 @@ final class PersistentDataStore {
serializer.text(Integer.toString(mColorMode));
serializer.endTag(null, TAG_COLOR_MODE);
- serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
- if (!Float.isNaN(mBrightness)) {
- serializer.text(Float.toString(mBrightness));
+ for (int i = 0; i < mPerUserBrightness.size(); i++) {
+ serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
+ serializer.attributeInt(null, ATTR_USER_SERIAL, mPerUserBrightness.keyAt(i));
+ serializer.text(Float.toString(mPerUserBrightness.valueAt(i)));
+ serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
}
- serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
mDisplayBrightnessConfigurations.saveToXml(serializer);
@@ -785,12 +793,33 @@ final class PersistentDataStore {
public void dump(final PrintWriter pw, final String prefix) {
pw.println(prefix + "ColorMode=" + mColorMode);
- pw.println(prefix + "BrightnessValue=" + mBrightness);
+ pw.println(prefix + "BrightnessValues: ");
+ for (int i = 0; i < mPerUserBrightness.size(); i++) {
+ pw.println("User: " + mPerUserBrightness.keyAt(i)
+ + " Value: " + mPerUserBrightness.valueAt(i));
+ }
pw.println(prefix + "DisplayBrightnessConfigurations: ");
mDisplayBrightnessConfigurations.dump(pw, prefix);
pw.println(prefix + "Resolution=" + mWidth + " " + mHeight);
pw.println(prefix + "RefreshRate=" + mRefreshRate);
}
+
+ private void loadBrightnessFromXml(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ int userSerial;
+ try {
+ userSerial = parser.getAttributeInt(null, ATTR_USER_SERIAL);
+ } catch (NumberFormatException | XmlPullParserException e) {
+ userSerial = DEFAULT_USER_ID;
+ Slog.e(TAG, "Failed to read user serial", e);
+ }
+ String brightness = parser.nextText();
+ try {
+ mPerUserBrightness.set(userSerial, Float.parseFloat(brightness));
+ } catch (NumberFormatException nfe) {
+ Slog.e(TAG, "Failed to read brightness", nfe);
+ }
+ }
}
private static final class StableDeviceValues {
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 7574de841440..2f52b708dfb5 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -38,6 +38,8 @@ import java.io.PrintWriter;
* display. Applies the chosen brightness.
*/
public final class DisplayBrightnessController {
+ private static final int DEFAULT_USER_SERIAL = -1;
+
// The ID of the display tied to this DisplayBrightnessController
private final int mDisplayId;
@@ -274,8 +276,16 @@ public final class DisplayBrightnessController {
* Notifies the brightnessSetting to persist the supplied brightness value.
*/
public void setBrightness(float brightnessValue) {
+ setBrightness(brightnessValue, DEFAULT_USER_SERIAL);
+ }
+
+ /**
+ * Notifies the brightnessSetting to persist the supplied brightness value for a user.
+ */
+ public void setBrightness(float brightnessValue, int userSerial) {
// Update the setting, which will eventually call back into DPC to have us actually
// update the display with the new value.
+ mBrightnessSetting.setUserSerial(userSerial);
mBrightnessSetting.setBrightness(brightnessValue);
if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
float nits = convertToNits(brightnessValue);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index cede2738cff0..3eab4b0b1835 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -63,10 +63,12 @@ import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
import android.hardware.hdmi.IHdmiVendorCommandListener;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.media.AudioAttributes;
+import android.media.AudioDescriptor;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioDeviceVolumeManager;
import android.media.AudioManager;
+import android.media.AudioProfile;
import android.media.VolumeInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
@@ -1577,6 +1579,10 @@ public class HdmiControlService extends SystemService {
// If the device is not TV, we can't convert path to port-id, so stop here.
return true;
}
+ // Invalidate the physical address if parameters length is too short.
+ if (params.length < offset + 2) {
+ return false;
+ }
int path = HdmiUtils.twoBytesToInt(params, offset);
if (path != Constants.INVALID_PHYSICAL_ADDRESS && path == getPhysicalAddress()) {
return true;
@@ -4723,13 +4729,24 @@ public class HdmiControlService extends SystemService {
Slog.w(TAG, "Tried to update eARC status on a port that doesn't support eARC.");
return;
}
- // If eARC is disabled, the local device is null. In this case, the HAL shouldn't have
- // reported connection state changes, but even if it did, it won't take effect.
if (mEarcLocalDevice != null) {
mEarcLocalDevice.handleEarcStateChange(status);
+ } else if (status == HDMI_EARC_STATUS_ARC_PENDING) {
+ // If eARC is disabled, the local device is null. This is why we notify
+ // AudioService here that the eARC connection is terminated.
+ notifyEarcStatusToAudioService(false, new ArrayList<>());
+ startArcAction(true, null);
}
}
+ protected void notifyEarcStatusToAudioService(
+ boolean enabled, List<AudioDescriptor> audioDescriptors) {
+ AudioDeviceAttributes attributes = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI_EARC, "", "",
+ new ArrayList<AudioProfile>(), audioDescriptors);
+ getAudioManager().setWiredDeviceConnectionState(attributes, enabled ? 1 : 0);
+ }
+
@ServiceThreadOnly
void handleEarcCapabilitiesReported(byte[] rawCapabilities, int portId) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
index 9058c984f958..4bc20a555dec 100644
--- a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
+++ b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
@@ -23,8 +23,6 @@ import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_IDLE;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.AudioDescriptor;
-import android.media.AudioDeviceAttributes;
-import android.media.AudioDeviceInfo;
import android.media.AudioProfile;
import android.os.Handler;
import android.util.IndentingPrintWriter;
@@ -44,6 +42,12 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
// How long to wait for the audio system to report its capabilities after eARC was connected
static final long REPORT_CAPS_MAX_DELAY_MS = 2_000;
+ // Array containing the names of the eARC states. The integer value of the eARC state
+ // corresponds to the index in the array.
+ private static final String earcStatusNames[] = {"HDMI_EARC_STATUS_IDLE",
+ "HDMI_EARC_STATUS_EARC_PENDING", "HDMI_EARC_STATUS_ARC_PENDING",
+ "HDMI_EARC_STATUS_EARC_CONNECTED"};
+
// eARC Capability Data Structure parameters
private static final int EARC_CAPS_PAYLOAD_LENGTH = 0x02;
private static final int EARC_CAPS_DATA_START = 0x03;
@@ -77,21 +81,27 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
mReportCapsRunnable = new ReportCapsRunnable();
}
+ private String earcStatusToString(int status) {
+ return earcStatusNames[status];
+ }
+
protected void handleEarcStateChange(@Constants.EarcStatus int status) {
int oldEarcStatus;
+
synchronized (mLock) {
- HdmiLogger.debug("eARC state change [old:%b new %b]", mEarcStatus,
- status);
+ HdmiLogger.debug("eARC state change [old: %s(%d) new: %s(%d)]",
+ earcStatusToString(mEarcStatus), mEarcStatus,
+ earcStatusToString(status), status);
oldEarcStatus = mEarcStatus;
mEarcStatus = status;
}
mReportCapsHandler.removeCallbacksAndMessages(null);
if (status == HDMI_EARC_STATUS_IDLE) {
- notifyEarcStatusToAudioService(false, new ArrayList<>());
+ mService.notifyEarcStatusToAudioService(false, new ArrayList<>());
mService.startArcAction(false, null);
} else if (status == HDMI_EARC_STATUS_ARC_PENDING) {
- notifyEarcStatusToAudioService(false, new ArrayList<>());
+ mService.notifyEarcStatusToAudioService(false, new ArrayList<>());
mService.startArcAction(true, null);
} else if (status == HDMI_EARC_STATUS_EARC_PENDING
&& oldEarcStatus == HDMI_EARC_STATUS_ARC_PENDING) {
@@ -110,19 +120,11 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
&& mReportCapsHandler.hasCallbacks(mReportCapsRunnable)) {
mReportCapsHandler.removeCallbacksAndMessages(null);
List<AudioDescriptor> audioDescriptors = parseCapabilities(rawCapabilities);
- notifyEarcStatusToAudioService(true, audioDescriptors);
+ mService.notifyEarcStatusToAudioService(true, audioDescriptors);
}
}
}
- private void notifyEarcStatusToAudioService(
- boolean enabled, List<AudioDescriptor> audioDescriptors) {
- AudioDeviceAttributes attributes = new AudioDeviceAttributes(
- AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI_EARC, "", "",
- new ArrayList<AudioProfile>(), audioDescriptors);
- mService.getAudioManager().setWiredDeviceConnectionState(attributes, enabled ? 1 : 0);
- }
-
/**
* Runnable for waiting for a certain amount of time for the audio system to report its
* capabilities after eARC was connected. If the audio system doesn´t report its capabilities in
@@ -134,7 +136,7 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
public void run() {
synchronized (mLock) {
if (mEarcStatus == HDMI_EARC_STATUS_EARC_CONNECTED) {
- notifyEarcStatusToAudioService(true, new ArrayList<>());
+ mService.notifyEarcStatusToAudioService(true, new ArrayList<>());
}
}
}
diff --git a/services/core/java/com/android/server/input/InputFeatureFlagProvider.java b/services/core/java/com/android/server/input/InputFeatureFlagProvider.java
index 3854adad9cd8..7c7f1513bd96 100644
--- a/services/core/java/com/android/server/input/InputFeatureFlagProvider.java
+++ b/services/core/java/com/android/server/input/InputFeatureFlagProvider.java
@@ -38,8 +38,15 @@ public final class InputFeatureFlagProvider {
private static final boolean KEYBOARD_BACKLIGHT_ANIMATION_ENABLED =
InputProperties.enable_keyboard_backlight_animation().orElse(false);
+ // To disable Custom keyboard backlight levels support via IDC files run:
+ // adb shell setprop persist.input.keyboard_backlight_custom_levels.enabled false (requires
+ // restart)
+ private static final boolean KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED =
+ InputProperties.enable_keyboard_backlight_custom_levels().orElse(true);
+
private static Optional<Boolean> sKeyboardBacklightControlOverride = Optional.empty();
private static Optional<Boolean> sKeyboardBacklightAnimationOverride = Optional.empty();
+ private static Optional<Boolean> sKeyboardBacklightCustomLevelsOverride = Optional.empty();
public static boolean isKeyboardBacklightControlEnabled() {
return sKeyboardBacklightControlOverride.orElse(KEYBOARD_BACKLIGHT_CONTROL_ENABLED);
@@ -49,6 +56,11 @@ public final class InputFeatureFlagProvider {
return sKeyboardBacklightAnimationOverride.orElse(KEYBOARD_BACKLIGHT_ANIMATION_ENABLED);
}
+ public static boolean isKeyboardBacklightCustomLevelsEnabled() {
+ return sKeyboardBacklightCustomLevelsOverride.orElse(
+ KEYBOARD_BACKLIGHT_CUSTOM_LEVELS_ENABLED);
+ }
+
public static void setKeyboardBacklightControlEnabled(boolean enabled) {
sKeyboardBacklightControlOverride = Optional.of(enabled);
}
@@ -57,11 +69,16 @@ public final class InputFeatureFlagProvider {
sKeyboardBacklightAnimationOverride = Optional.of(enabled);
}
+ public static void setKeyboardBacklightCustomLevelsEnabled(boolean enabled) {
+ sKeyboardBacklightCustomLevelsOverride = Optional.of(enabled);
+ }
+
/**
* Clears all input feature flag overrides.
*/
public static void clearOverrides() {
sKeyboardBacklightControlOverride = Optional.empty();
sKeyboardBacklightAnimationOverride = Optional.empty();
+ sKeyboardBacklightCustomLevelsOverride = Optional.empty();
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 9f3ab885bf16..c7b80af27d79 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -493,8 +493,6 @@ public class InputManagerService extends IInputManager.Stub
// Add ourselves to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
-
- mSettingsObserver.registerAndUpdate();
}
// TODO(BT) Pass in parameter for bluetooth system
@@ -505,6 +503,8 @@ public class InputManagerService extends IInputManager.Stub
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
+ mSettingsObserver.registerAndUpdate();
+
synchronized (mLidSwitchLock) {
mSystemReady = true;
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 651063e8841b..42591f40b22e 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -115,35 +115,34 @@ class InputSettingsObserver extends ContentObserver {
return setting != 0;
}
- private int getPointerSpeedValue(String settingName) {
- int speed = Settings.System.getIntForUser(mContext.getContentResolver(),
- settingName, InputSettings.DEFAULT_POINTER_SPEED, UserHandle.USER_CURRENT);
+ private int constrainPointerSpeedValue(int speed) {
return Math.min(Math.max(speed, InputSettings.MIN_POINTER_SPEED),
InputSettings.MAX_POINTER_SPEED);
}
private void updateMousePointerSpeed() {
- mNative.setPointerSpeed(getPointerSpeedValue(Settings.System.POINTER_SPEED));
+ int speed = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED, InputSettings.DEFAULT_POINTER_SPEED,
+ UserHandle.USER_CURRENT);
+ mNative.setPointerSpeed(constrainPointerSpeedValue(speed));
}
private void updateTouchpadPointerSpeed() {
mNative.setTouchpadPointerSpeed(
- getPointerSpeedValue(Settings.System.TOUCHPAD_POINTER_SPEED));
+ constrainPointerSpeedValue(InputSettings.getTouchpadPointerSpeed(mContext)));
}
private void updateTouchpadNaturalScrollingEnabled() {
mNative.setTouchpadNaturalScrollingEnabled(
- getBoolean(Settings.System.TOUCHPAD_NATURAL_SCROLLING, true));
+ InputSettings.useTouchpadNaturalScrolling(mContext));
}
private void updateTouchpadTapToClickEnabled() {
- mNative.setTouchpadTapToClickEnabled(
- getBoolean(Settings.System.TOUCHPAD_TAP_TO_CLICK, true));
+ mNative.setTouchpadTapToClickEnabled(InputSettings.useTouchpadTapToClick(mContext));
}
private void updateTouchpadRightClickZoneEnabled() {
- mNative.setTouchpadRightClickZoneEnabled(
- getBoolean(Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, false));
+ mNative.setTouchpadRightClickZoneEnabled(InputSettings.useTouchpadRightClickZone(mContext));
}
private void updateShowTouches() {
diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java
index 61ca0cbff7bf..36238a8cfd23 100644
--- a/services/core/java/com/android/server/input/KeyboardBacklightController.java
+++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java
@@ -46,6 +46,7 @@ import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;
import java.util.OptionalInt;
+import java.util.TreeSet;
/**
* A thread-safe component of {@link InputManagerService} responsible for managing the keyboard
@@ -70,7 +71,9 @@ final class KeyboardBacklightController implements
private static final int MSG_NOTIFY_USER_INACTIVITY = 5;
private static final int MSG_INTERACTIVE_STATE_CHANGED = 6;
private static final int MAX_BRIGHTNESS = 255;
- private static final int NUM_BRIGHTNESS_CHANGE_STEPS = 10;
+ private static final int DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS = 10;
+ @VisibleForTesting
+ static final int MAX_BRIGHTNESS_CHANGE_STEPS = 10;
private static final long TRANSITION_ANIMATION_DURATION_MILLIS =
Duration.ofSeconds(1).toMillis();
@@ -80,7 +83,8 @@ final class KeyboardBacklightController implements
static final long USER_INACTIVITY_THRESHOLD_MILLIS = Duration.ofSeconds(30).toMillis();
@VisibleForTesting
- static final int[] BRIGHTNESS_VALUE_FOR_LEVEL = new int[NUM_BRIGHTNESS_CHANGE_STEPS + 1];
+ static final int[] DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL =
+ new int[DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS + 1];
private final Context mContext;
private final NativeInputManagerService mNative;
@@ -104,10 +108,10 @@ final class KeyboardBacklightController implements
static {
// Fixed brightness levels to avoid issues when converting back and forth from the
// device brightness range to [0-255]
- // Levels are: 0, 25, 51, ..., 255
- for (int i = 0; i <= NUM_BRIGHTNESS_CHANGE_STEPS; i++) {
- BRIGHTNESS_VALUE_FOR_LEVEL[i] = (int) Math.floor(
- ((float) i * MAX_BRIGHTNESS) / NUM_BRIGHTNESS_CHANGE_STEPS);
+ // Levels are: 0, 51, ..., 255
+ for (int i = 0; i <= DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS; i++) {
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[i] = (int) Math.floor(
+ ((float) i * MAX_BRIGHTNESS) / DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS);
}
}
@@ -184,7 +188,8 @@ final class KeyboardBacklightController implements
final int currBrightnessLevel = state.mBrightnessLevel;
final int newBrightnessLevel;
if (direction == Direction.DIRECTION_UP) {
- newBrightnessLevel = Math.min(currBrightnessLevel + 1, NUM_BRIGHTNESS_CHANGE_STEPS);
+ newBrightnessLevel = Math.min(currBrightnessLevel + 1,
+ state.getNumBrightnessChangeSteps());
} else {
newBrightnessLevel = Math.max(currBrightnessLevel - 1, 0);
}
@@ -194,7 +199,7 @@ final class KeyboardBacklightController implements
try {
mDataStore.setKeyboardBacklightBrightness(inputDevice.getDescriptor(),
keyboardBacklight.getId(),
- BRIGHTNESS_VALUE_FOR_LEVEL[newBrightnessLevel]);
+ state.mBrightnessValueForLevel[newBrightnessLevel]);
} finally {
mDataStore.saveIfNeeded();
}
@@ -202,6 +207,7 @@ final class KeyboardBacklightController implements
}
private void restoreBacklightBrightness(InputDevice inputDevice, Light keyboardBacklight) {
+ KeyboardBacklightState state = mKeyboardBacklights.get(inputDevice.getId());
OptionalInt brightness;
synchronized (mDataStore) {
brightness = mDataStore.getKeyboardBacklightBrightness(
@@ -209,9 +215,9 @@ final class KeyboardBacklightController implements
}
if (brightness.isPresent()) {
int brightnessValue = Math.max(0, Math.min(MAX_BRIGHTNESS, brightness.getAsInt()));
- int index = Arrays.binarySearch(BRIGHTNESS_VALUE_FOR_LEVEL, brightnessValue);
+ int index = Arrays.binarySearch(state.mBrightnessValueForLevel, brightnessValue);
if (index < 0) {
- index = Math.min(NUM_BRIGHTNESS_CHANGE_STEPS, -(index + 1));
+ index = Math.min(state.getNumBrightnessChangeSteps(), -(index + 1));
}
updateBacklightState(inputDevice.getId(), index, false /* isTriggeredByKeyPress */);
if (DEBUG) {
@@ -386,7 +392,7 @@ final class KeyboardBacklightController implements
for (int i = 0; i < mKeyboardBacklightListenerRecords.size(); i++) {
IKeyboardBacklightState callbackState = new IKeyboardBacklightState();
callbackState.brightnessLevel = brightnessLevel;
- callbackState.maxBrightnessLevel = NUM_BRIGHTNESS_CHANGE_STEPS;
+ callbackState.maxBrightnessLevel = state.getNumBrightnessChangeSteps();
mKeyboardBacklightListenerRecords.valueAt(i).notifyKeyboardBacklightChanged(
deviceId, callbackState, isTriggeredByKeyPress);
}
@@ -443,10 +449,6 @@ final class KeyboardBacklightController implements
ipw.decreaseIndent();
}
- private static boolean isAnimationEnabled() {
- return InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled();
- }
-
// A record of a registered Keyboard backlight listener from one process.
private class KeyboardBacklightListenerRecord implements IBinder.DeathRecipient {
public final int mPid;
@@ -482,18 +484,52 @@ final class KeyboardBacklightController implements
private final Light mLight;
private int mBrightnessLevel;
private ValueAnimator mAnimator;
+ private final int[] mBrightnessValueForLevel;
KeyboardBacklightState(int deviceId, Light light) {
mDeviceId = deviceId;
mLight = light;
+ mBrightnessValueForLevel = setupBrightnessLevels();
+ }
+
+ private int[] setupBrightnessLevels() {
+ if (!InputFeatureFlagProvider.isKeyboardBacklightCustomLevelsEnabled()) {
+ return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
+ }
+ int[] customLevels = mLight.getPreferredBrightnessLevels();
+ if (customLevels == null || customLevels.length == 0) {
+ return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
+ }
+ TreeSet<Integer> brightnessLevels = new TreeSet<>();
+ brightnessLevels.add(0);
+ for (int level : customLevels) {
+ if (level > 0 && level < MAX_BRIGHTNESS) {
+ brightnessLevels.add(level);
+ }
+ }
+ brightnessLevels.add(MAX_BRIGHTNESS);
+ int brightnessChangeSteps = brightnessLevels.size() - 1;
+ if (brightnessChangeSteps > MAX_BRIGHTNESS_CHANGE_STEPS) {
+ return DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL;
+ }
+ int[] result = new int[brightnessLevels.size()];
+ int index = 0;
+ for (int val : brightnessLevels) {
+ result[index++] = val;
+ }
+ return result;
+ }
+
+ private int getNumBrightnessChangeSteps() {
+ return mBrightnessValueForLevel.length - 1;
}
private void onBacklightStateChanged() {
- setBacklightValue(mIsBacklightOn ? BRIGHTNESS_VALUE_FOR_LEVEL[mBrightnessLevel] : 0);
+ setBacklightValue(mIsBacklightOn ? mBrightnessValueForLevel[mBrightnessLevel] : 0);
}
private void setBrightnessLevel(int brightnessLevel) {
if (mIsBacklightOn) {
- setBacklightValue(BRIGHTNESS_VALUE_FOR_LEVEL[brightnessLevel]);
+ setBacklightValue(mBrightnessValueForLevel[brightnessLevel]);
}
mBrightnessLevel = brightnessLevel;
}
@@ -509,7 +545,7 @@ final class KeyboardBacklightController implements
if (fromValue == toValue) {
return;
}
- if (isAnimationEnabled()) {
+ if (InputFeatureFlagProvider.isKeyboardBacklightAnimationEnabled()) {
startAnimation(fromValue, toValue);
} else {
mNative.setLightColor(mDeviceId, mLight.getId(), Color.argb(toValue, 0, 0, 0));
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 6ec4022fe15a..611a61a2e272 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -252,6 +252,8 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
if (needToShowNotification) {
maybeUpdateNotification();
}
+ // TODO (b/280421650): Implement logging statements using KeyboardMetricsCollector
+ // for KeyboardConfigured atom
}
private String getDefaultKeyboardLayout(final InputDevice inputDevice) {
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
new file mode 100644
index 000000000000..b8f57f555c0e
--- /dev/null
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.hardware.input.KeyboardLayout;
+import android.util.proto.ProtoOutputStream;
+import android.view.InputDevice;
+
+import com.android.internal.os.KeyboardConfiguredProto.KeyboardLayoutConfig;
+import com.android.internal.os.KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.util.List;
+
+/**
+ * Collect Keyboard metrics
+ */
+public final class KeyboardMetricsCollector {
+ private static final String TAG = "KeyboardMetricCollector";
+
+ /**
+ * Log keyboard system shortcuts for the proto
+ * {@link com.android.os.input.KeyboardSystemsEventReported}
+ * defined in "stats/atoms/input/input_extension_atoms.proto"
+ */
+ public static void logKeyboardSystemsEventReportedAtom(InputDevice inputDevice,
+ int keyboardSystemEvent, int[] keyCode, int modifierState) {
+ int vendor_id = inputDevice.getVendorId();
+ int product_id = inputDevice.getProductId();
+ FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
+ vendor_id, product_id, keyboardSystemEvent, keyCode, modifierState);
+ }
+
+ /**
+ * Function to log the KeyboardConfigured
+ * {@link com.android.os.input.KeyboardConfigured} atom
+ *
+ * @param inputDevice Input device
+ * @param keyboardLayoutConfigurations List of keyboard configurations
+ * @param isFirstTimeConfiguration Whether keyboard is configured for the first time
+ */
+ public static void logKeyboardConfiguredAtom(InputDevice inputDevice,
+ List<KeyboardLayoutConfiguration> keyboardLayoutConfigurations,
+ boolean isFirstTimeConfiguration) {
+ int vendor_id = inputDevice.getVendorId();
+ int product_id = inputDevice.getProductId();
+
+ // Creating proto to log nested field KeyboardLayoutConfig in atom
+ ProtoOutputStream proto = new ProtoOutputStream();
+
+ for (KeyboardLayoutConfiguration keyboardLayoutConfiguration :
+ keyboardLayoutConfigurations) {
+ addKeyboardLayoutConfigurationToProto(proto, keyboardLayoutConfiguration);
+ }
+ // Push the atom to Statsd
+ FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_CONFIGURED,
+ isFirstTimeConfiguration, vendor_id, product_id, proto.getBytes());
+ }
+
+ /**
+ * Populate the KeyboardLayoutConfig proto which is a repeated proto
+ * in the RepeatedKeyboardLayoutConfig proto with values from the
+ * {@link KeyboardLayoutConfiguration} class
+ * The proto definitions can be found at:
+ * "frameworks/proto_logging/stats/atoms/input/input_extension_atoms.proto"
+ *
+ * @param proto Representing the nested proto RepeatedKeyboardLayoutConfig
+ * @param keyboardLayoutConfiguration Class containing the fields for populating the
+ * KeyboardLayoutConfig proto
+ */
+ private static void addKeyboardLayoutConfigurationToProto(ProtoOutputStream proto,
+ KeyboardLayoutConfiguration keyboardLayoutConfiguration) {
+ // Start a new KeyboardLayoutConfig proto.
+ long keyboardLayoutConfigToken = proto.start(
+ RepeatedKeyboardLayoutConfig.KEYBOARD_LAYOUT_CONFIG);
+ proto.write(KeyboardLayoutConfig.KEYBOARD_LANGUAGE_TAG,
+ keyboardLayoutConfiguration.getKeyboardLanguageTag());
+ proto.write(KeyboardLayoutConfig.KEYBOARD_LAYOUT_TYPE,
+ keyboardLayoutConfiguration.getKeyboardLayoutType());
+ proto.write(KeyboardLayoutConfig.KEYBOARD_LAYOUT_NAME,
+ keyboardLayoutConfiguration.getKeyboardLayoutName());
+ proto.write(KeyboardLayoutConfig.LAYOUT_SELECTION_CRITERIA,
+ keyboardLayoutConfiguration.getLayoutSelectionCriteria());
+ proto.end(keyboardLayoutConfigToken);
+ }
+
+ /**
+ * Java class representing the proto KeyboardLayoutConfig defined in
+ * "frameworks/proto_logging/stats/atoms/input/input_extension_atoms.proto"
+ *
+ * @see com.android.os.input.KeyboardConfigured
+ */
+ public static class KeyboardLayoutConfiguration {
+ // KeyboardLayoutType in "frameworks/base/core/res/res/values/attrs.xml"
+ // contains mapping for enums to int
+ int mKeyboardLayoutType;
+ String mKeyboardLanguageTag;
+ KeyboardLayout mKeyboardLayout;
+ @LayoutSelectionCriteria int mLayoutSelectionCriteria;
+
+ @Retention(SOURCE)
+ @IntDef(prefix = { "LAYOUT_SELECTION_CRITERIA_" }, value = {
+ LAYOUT_SELECTION_CRITERIA_USER,
+ LAYOUT_SELECTION_CRITERIA_DEVICE,
+ LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD
+ })
+ public @interface LayoutSelectionCriteria {}
+
+ /** Manual selection by user */
+ public static final int LAYOUT_SELECTION_CRITERIA_USER = 0;
+
+ /** Auto-detection based on device provided language tag and layout type */
+ public static final int LAYOUT_SELECTION_CRITERIA_DEVICE = 1;
+
+ /** Auto-detection based on IME provided language tag and layout type */
+ public static final int LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD = 2;
+
+ KeyboardLayoutConfiguration(int keyboardLayoutType,
+ String keyboardLanguageTag,
+ KeyboardLayout keyboardLayout,
+ @LayoutSelectionCriteria int layoutSelectionCriteria) {
+ mKeyboardLayoutType = keyboardLayoutType;
+ mKeyboardLanguageTag = keyboardLanguageTag;
+ mKeyboardLayout = keyboardLayout;
+ mLayoutSelectionCriteria = layoutSelectionCriteria;
+ }
+ int getKeyboardLayoutType() {
+ return mKeyboardLayoutType;
+ }
+
+ String getKeyboardLanguageTag() {
+ return mKeyboardLanguageTag;
+ }
+
+ String getKeyboardLayoutName() {
+ return mKeyboardLayout.getLabel();
+ }
+
+ @LayoutSelectionCriteria int getLayoutSelectionCriteria() {
+ return mLayoutSelectionCriteria;
+ }
+ }
+}
+
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 20f06971b6b2..2e62ef4f8566 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -889,22 +889,31 @@ public class LockSettingsService extends ILockSettings.Stub {
}
- private void migrateOldDataAfterSystemReady() {
- // Migrate the FRP credential to the persistent data block
+ @VisibleForTesting
+ void migrateOldDataAfterSystemReady() {
+ // Write the FRP persistent data block if needed.
+ //
+ // The original purpose of this code was to write the FRP block for the first time, when
+ // upgrading from Android 8.1 or earlier which didn't use the FRP block. This code has
+ // since been repurposed to also fix the "bad" (non-forwards-compatible) FRP block written
+ // by Android 14 Beta 2. For this reason, the database key used here has been renamed from
+ // "migrated_frp" to "migrated_frp2" to cause migrateFrpCredential() to run again on devices
+ // where it had run before.
if (LockPatternUtils.frpCredentialEnabled(mContext)
- && !getBoolean("migrated_frp", false, 0)) {
+ && !getBoolean("migrated_frp2", false, 0)) {
migrateFrpCredential();
- setBoolean("migrated_frp", true, 0);
+ setBoolean("migrated_frp2", true, 0);
}
}
/**
- * Migrate the credential for the FRP credential owner user if the following are satisfied:
- * - the user has a secure credential
- * - the FRP credential is not set up
+ * Write the FRP persistent data block if the following are satisfied:
+ * - the user who owns the FRP credential has a nonempty credential
+ * - the FRP persistent data block doesn't exist or uses the "bad" format from Android 14 Beta 2
*/
private void migrateFrpCredential() {
- if (mStorage.readPersistentDataBlock() != PersistentData.NONE) {
+ PersistentData data = mStorage.readPersistentDataBlock();
+ if (data != PersistentData.NONE && !data.isBadFormatFromAndroid14Beta()) {
return;
}
for (UserInfo userInfo : mUserManager.getUsers()) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 731ecadc1372..2fa637e030f1 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -606,6 +606,11 @@ class LockSettingsStorage {
this.payload = payload;
}
+ public boolean isBadFormatFromAndroid14Beta() {
+ return (this.type == TYPE_SP_GATEKEEPER || this.type == TYPE_SP_WEAVER)
+ && SyntheticPasswordManager.PasswordData.isBadFormatFromAndroid14Beta(this.payload);
+ }
+
public static PersistentData fromBytes(byte[] frpData) {
if (frpData == null || frpData.length == 0) {
return NONE;
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 65e7a00ad13f..66f862ac9205 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -370,6 +370,15 @@ class SyntheticPasswordManager {
return result;
}
+ /**
+ * Returns true if the given serialized PasswordData begins with the value 2 as a short.
+ * This detects the "bad" (non-forwards-compatible) PasswordData format that was temporarily
+ * used during development of Android 14. For more details, see fromBytes() below.
+ */
+ public static boolean isBadFormatFromAndroid14Beta(byte[] data) {
+ return data != null && data.length >= 2 && data[0] == 0 && data[1] == 2;
+ }
+
public static PasswordData fromBytes(byte[] data) {
PasswordData result = new PasswordData();
ByteBuffer buffer = ByteBuffer.allocate(data.length);
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index c076c0574afe..c59b73350865 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -31,6 +31,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
abstract class MediaRoute2Provider {
final ComponentName mComponentName;
@@ -56,7 +57,9 @@ abstract class MediaRoute2Provider {
public abstract void requestCreateSession(long requestId, String packageName, String routeId,
@Nullable Bundle sessionHints);
public abstract void releaseSession(long requestId, String sessionId);
- public abstract void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference);
+
+ public abstract void updateDiscoveryPreference(
+ Set<String> activelyScanningPackages, RouteDiscoveryPreference discoveryPreference);
public abstract void selectRoute(long requestId, String sessionId, String routeId);
public abstract void deselectRoute(long requestId, String sessionId, String routeId);
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index 72b843672ae8..3cf0786b7e28 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -49,6 +49,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Maintains a connection to a particular {@link MediaRoute2ProviderService}.
@@ -61,6 +62,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
private final Context mContext;
private final int mUserId;
private final Handler mHandler;
+ private final boolean mIsSelfScanOnlyProvider;
// Connection state
private boolean mRunning;
@@ -70,14 +72,19 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
private boolean mIsManagerScanning;
private RouteDiscoveryPreference mLastDiscoveryPreference = null;
+ private boolean mLastDiscoveryPreferenceIncludesThisPackage = false;
@GuardedBy("mLock")
final List<RoutingSessionInfo> mReleasingSessions = new ArrayList<>();
- MediaRoute2ProviderServiceProxy(@NonNull Context context, @NonNull ComponentName componentName,
+ MediaRoute2ProviderServiceProxy(
+ @NonNull Context context,
+ @NonNull ComponentName componentName,
+ boolean isSelfScanOnlyProvider,
int userId) {
super(componentName);
mContext = Objects.requireNonNull(context, "Context must not be null.");
+ mIsSelfScanOnlyProvider = isSelfScanOnlyProvider;
mUserId = userId;
mHandler = new Handler(Looper.myLooper());
}
@@ -107,8 +114,11 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
@Override
- public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
+ public void updateDiscoveryPreference(
+ Set<String> activelyScanningPackages, RouteDiscoveryPreference discoveryPreference) {
mLastDiscoveryPreference = discoveryPreference;
+ mLastDiscoveryPreferenceIncludesThisPackage =
+ activelyScanningPackages.contains(mComponentName.getPackageName());
if (mConnectionReady) {
mActiveConnection.updateDiscoveryPreference(discoveryPreference);
}
@@ -209,11 +219,15 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
private boolean shouldBind() {
if (mRunning) {
- // Bind when there is a discovery preference or an active route session.
- return (mLastDiscoveryPreference != null
- && !mLastDiscoveryPreference.getPreferredFeatures().isEmpty())
- || !getSessionInfos().isEmpty()
- || mIsManagerScanning;
+ boolean shouldBind =
+ mLastDiscoveryPreference != null
+ && !mLastDiscoveryPreference.getPreferredFeatures().isEmpty();
+ if (mIsSelfScanOnlyProvider) {
+ shouldBind &= mLastDiscoveryPreferenceIncludesThisPackage;
+ }
+ shouldBind |= mIsManagerScanning;
+ shouldBind |= !getSessionInfos().isEmpty();
+ return shouldBind;
}
return false;
}
@@ -301,7 +315,11 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
if (mActiveConnection == connection) {
mConnectionReady = true;
if (mLastDiscoveryPreference != null) {
- updateDiscoveryPreference(mLastDiscoveryPreference);
+ updateDiscoveryPreference(
+ mLastDiscoveryPreferenceIncludesThisPackage
+ ? Set.of(mComponentName.getPackageName())
+ : Set.of(),
+ mLastDiscoveryPreference);
}
}
}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 46bccaf314d9..bd252e7fdfd2 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -16,6 +16,8 @@
package com.android.server.media;
+import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
+
import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -34,6 +36,7 @@ import android.util.Slog;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
/**
* Watches changes of packages, or scan them for finding media route providers.
@@ -41,8 +44,8 @@ import java.util.Collections;
final class MediaRoute2ProviderWatcher {
private static final String TAG = "MR2ProviderWatcher";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final PackageManager.ResolveInfoFlags RESOLVE_INFO_FLAGS_NONE =
- PackageManager.ResolveInfoFlags.of(0);
+ private static final PackageManager.ResolveInfoFlags RESOLVE_INFO_FLAGS =
+ PackageManager.ResolveInfoFlags.of(GET_RESOLVED_FILTER);
private final Context mContext;
private final Callback mCallback;
@@ -118,16 +121,26 @@ final class MediaRoute2ProviderWatcher {
int targetIndex = 0;
Intent intent = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
for (ResolveInfo resolveInfo :
- mPackageManager.queryIntentServicesAsUser(
- intent, RESOLVE_INFO_FLAGS_NONE, mUserId)) {
+ mPackageManager.queryIntentServicesAsUser(intent, RESOLVE_INFO_FLAGS, mUserId)) {
ServiceInfo serviceInfo = resolveInfo.serviceInfo;
if (serviceInfo != null) {
+ boolean isSelfScanOnlyProvider = false;
+ Iterator<String> categoriesIterator = resolveInfo.filter.categoriesIterator();
+ if (categoriesIterator != null) {
+ while (categoriesIterator.hasNext()) {
+ isSelfScanOnlyProvider |=
+ MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(
+ categoriesIterator.next());
+ }
+ }
int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
if (sourceIndex < 0) {
MediaRoute2ProviderServiceProxy proxy =
- new MediaRoute2ProviderServiceProxy(mContext,
- new ComponentName(serviceInfo.packageName, serviceInfo.name),
- mUserId);
+ new MediaRoute2ProviderServiceProxy(
+ mContext,
+ new ComponentName(serviceInfo.packageName, serviceInfo.name),
+ isSelfScanOnlyProvider,
+ mUserId);
proxy.start();
mProxies.add(targetIndex++, proxy);
mCallback.onAddProviderService(proxy);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index b79991e5d013..309a99ecdaee 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -1478,6 +1478,7 @@ class MediaRouter2ServiceImpl {
final ArrayList<RouterRecord> mRouterRecords = new ArrayList<>();
final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();
RouteDiscoveryPreference mCompositeDiscoveryPreference = RouteDiscoveryPreference.EMPTY;
+ Set<String> mActivelyScanningPackages = Set.of();
final UserHandler mHandler;
UserRecord(int userId) {
@@ -1525,7 +1526,12 @@ class MediaRouter2ServiceImpl {
pw.println(indent + "<no manager records>");
}
- mCompositeDiscoveryPreference.dump(pw, indent);
+ pw.println(indent + "Composite discovery preference:");
+ mCompositeDiscoveryPreference.dump(pw, indent + " ");
+ pw.println(
+ indent
+ + "Packages actively scanning: "
+ + String.join(", ", mActivelyScanningPackages));
if (!mHandler.runWithScissors(() -> mHandler.dump(pw, indent), 1000)) {
pw.println(indent + "<could not dump handler state>");
@@ -1638,6 +1644,26 @@ class MediaRouter2ServiceImpl {
}
/**
+ * Notifies the corresponding router that it was successfully registered.
+ *
+ * <p>The message sent to the router includes a snapshot of the initial state, including
+ * known routes and the system {@link RoutingSessionInfo}.
+ *
+ * @param currentRoutes All currently known routes, which are filtered according to package
+ * visibility before being sent to the router.
+ * @param currentSystemSessionInfo The current system {@link RoutingSessionInfo}.
+ */
+ public void notifyRegistered(
+ List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
+ try {
+ mRouter.notifyRouterRegistered(
+ getVisibleRoutes(currentRoutes), currentSystemSessionInfo);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to notify router registered. Router probably died.", ex);
+ }
+ }
+
+ /**
* Sends the corresponding router an {@link
* android.media.MediaRouter2.RouteCallback#onRoutesUpdated update} for the given {@code
* routes}.
@@ -1834,7 +1860,9 @@ class MediaRouter2ServiceImpl {
public void onAddProviderService(@NonNull MediaRoute2ProviderServiceProxy proxy) {
proxy.setCallback(this);
mRouteProviders.add(proxy);
- proxy.updateDiscoveryPreference(mUserRecord.mCompositeDiscoveryPreference);
+ proxy.updateDiscoveryPreference(
+ mUserRecord.mActivelyScanningPackages,
+ mUserRecord.mCompositeDiscoveryPreference);
}
@Override
@@ -2341,8 +2369,8 @@ class MediaRouter2ServiceImpl {
return;
}
notifySessionInfoChangedToRouters(getRouterRecords(true), sessionInfo);
- notifySessionInfoChangedToRouters(getRouterRecords(false),
- mSystemProvider.getDefaultSessionInfo());
+ notifySessionInfoChangedToRouters(
+ getRouterRecords(false), mSystemProvider.getDefaultSessionInfo());
return;
}
@@ -2536,12 +2564,7 @@ class MediaRouter2ServiceImpl {
return;
}
- try {
- routerRecord.mRouter.notifyRouterRegistered(
- currentRoutes, currentSystemSessionInfo);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify router registered. Router probably died.", ex);
- }
+ routerRecord.notifyRegistered(currentRoutes, currentSystemSessionInfo);
}
private static void notifyRoutesUpdatedToRouterRecords(
@@ -2711,8 +2734,8 @@ class MediaRouter2ServiceImpl {
if (service == null) {
return;
}
- List<RouteDiscoveryPreference> discoveryPreferences = Collections.emptyList();
- List<RouterRecord> routerRecords = getRouterRecords();
+ List<RouterRecord> activeRouterRecords = Collections.emptyList();
+ List<RouterRecord> allRouterRecords = getRouterRecords();
List<ManagerRecord> managerRecords = getManagerRecords();
boolean isManagerScanning = false;
@@ -2723,15 +2746,16 @@ class MediaRouter2ServiceImpl {
<= sPackageImportanceForScanning);
if (isManagerScanning) {
- discoveryPreferences = routerRecords.stream()
- .map(record -> record.mDiscoveryPreference)
- .collect(Collectors.toList());
+ activeRouterRecords = allRouterRecords;
} else {
- discoveryPreferences = routerRecords.stream().filter(record ->
- service.mActivityManager.getPackageImportance(record.mPackageName)
- <= sPackageImportanceForScanning)
- .map(record -> record.mDiscoveryPreference)
- .collect(Collectors.toList());
+ activeRouterRecords =
+ allRouterRecords.stream()
+ .filter(
+ record ->
+ service.mActivityManager.getPackageImportance(
+ record.mPackageName)
+ <= sPackageImportanceForScanning)
+ .collect(Collectors.toList());
}
}
@@ -2748,22 +2772,30 @@ class MediaRouter2ServiceImpl {
// to query route providers once to obtain all of the routes of interest, which
// can be subsequently filtered for the individual discovery preferences.
Set<String> preferredFeatures = new HashSet<>();
+ Set<String> activelyScanningPackages = new HashSet<>();
boolean activeScan = false;
- for (RouteDiscoveryPreference preference : discoveryPreferences) {
+ for (RouterRecord activeRouterRecord : activeRouterRecords) {
+ RouteDiscoveryPreference preference = activeRouterRecord.mDiscoveryPreference;
preferredFeatures.addAll(preference.getPreferredFeatures());
- activeScan |= preference.shouldPerformActiveScan();
+ if (preference.shouldPerformActiveScan()) {
+ activeScan = true;
+ activelyScanningPackages.add(activeRouterRecord.mPackageName);
+ }
}
RouteDiscoveryPreference newPreference = new RouteDiscoveryPreference.Builder(
List.copyOf(preferredFeatures), activeScan || isManagerScanning).build();
synchronized (service.mLock) {
- if (newPreference.equals(mUserRecord.mCompositeDiscoveryPreference)) {
+ if (newPreference.equals(mUserRecord.mCompositeDiscoveryPreference)
+ && activelyScanningPackages.equals(mUserRecord.mActivelyScanningPackages)) {
return;
}
mUserRecord.mCompositeDiscoveryPreference = newPreference;
+ mUserRecord.mActivelyScanningPackages = activelyScanningPackages;
}
for (MediaRoute2Provider provider : mRouteProviders) {
- provider.updateDiscoveryPreference(mUserRecord.mCompositeDiscoveryPreference);
+ provider.updateDiscoveryPreference(
+ activelyScanningPackages, mUserRecord.mCompositeDiscoveryPreference);
}
}
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 426bc5eed051..f4e6abd47b44 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -42,6 +42,7 @@ import com.android.internal.annotations.GuardedBy;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers.
@@ -196,7 +197,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
- public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
+ public void updateDiscoveryPreference(
+ Set<String> activelyScanningPackages, RouteDiscoveryPreference discoveryPreference) {
// Do nothing
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e56eba659d37..c496857bb63b 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6746,6 +6746,8 @@ public class NotificationManagerService extends SystemService {
return false;
}
+ mUsageStats.registerEnqueuedByAppAndAccepted(pkg);
+
if (info != null) {
// Cache the shortcut synchronously after the associated notification is posted in case
// the app unpublishes this shortcut immediately after posting the notification. If the
@@ -7184,11 +7186,12 @@ public class NotificationManagerService extends SystemService {
+ " cannot create notifications");
}
- // rate limit updates that aren't completed progress notifications
- if (mNotificationsByKey.get(r.getSbn().getKey()) != null
- && !r.getNotification().hasCompletedProgress()
- && !isAutogroup) {
-
+ // Rate limit updates that aren't completed progress notifications
+ // Search for the original one in the posted and not-yet-posted (enqueued) lists.
+ boolean isUpdate = mNotificationsByKey.get(r.getSbn().getKey()) != null
+ || findNotificationByListLocked(mEnqueuedNotifications, r.getSbn().getKey())
+ != null;
+ if (isUpdate && !r.getNotification().hasCompletedProgress() && !isAutogroup) {
final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
if (appEnqueueRate > mMaxPackageEnqueueRate) {
mUsageStats.registerOverRateQuota(pkg);
@@ -7813,15 +7816,8 @@ public class NotificationManagerService extends SystemService {
boolean posted = false;
synchronized (mNotificationLock) {
try {
- NotificationRecord r = null;
- int N = mEnqueuedNotifications.size();
- for (int i = 0; i < N; i++) {
- final NotificationRecord enqueued = mEnqueuedNotifications.get(i);
- if (Objects.equals(key, enqueued.getKey())) {
- r = enqueued;
- break;
- }
- }
+ NotificationRecord r = findNotificationByListLocked(mEnqueuedNotifications,
+ key);
if (r == null) {
Slog.i(TAG, "Cannot find enqueued record for key: " + key);
return false;
@@ -9486,7 +9482,7 @@ public class NotificationManagerService extends SystemService {
* Determine whether the userId applies to the notification in question, either because
* they match exactly, or one of them is USER_ALL (which is treated as a wildcard).
*/
- private boolean notificationMatchesUserId(NotificationRecord r, int userId) {
+ private static boolean notificationMatchesUserId(NotificationRecord r, int userId) {
return
// looking for USER_ALL notifications? match everything
userId == UserHandle.USER_ALL
@@ -9845,9 +9841,9 @@ public class NotificationManagerService extends SystemService {
return null;
}
- @GuardedBy("mNotificationLock")
- private NotificationRecord findNotificationByListLocked(ArrayList<NotificationRecord> list,
- String pkg, String tag, int id, int userId) {
+ @Nullable
+ private static NotificationRecord findNotificationByListLocked(
+ ArrayList<NotificationRecord> list, String pkg, String tag, int id, int userId) {
final int len = list.size();
for (int i = 0; i < len; i++) {
NotificationRecord r = list.get(i);
@@ -9860,8 +9856,7 @@ public class NotificationManagerService extends SystemService {
return null;
}
- @GuardedBy("mNotificationLock")
- private List<NotificationRecord> findNotificationsByListLocked(
+ private static List<NotificationRecord> findNotificationsByListLocked(
ArrayList<NotificationRecord> list, String pkg, String tag, int id, int userId) {
List<NotificationRecord> matching = new ArrayList<>();
final int len = list.size();
@@ -9876,9 +9871,9 @@ public class NotificationManagerService extends SystemService {
return matching;
}
- @GuardedBy("mNotificationLock")
- private NotificationRecord findNotificationByListLocked(ArrayList<NotificationRecord> list,
- String key) {
+ @Nullable
+ private static NotificationRecord findNotificationByListLocked(
+ ArrayList<NotificationRecord> list, String key) {
final int N = list.size();
for (int i = 0; i < N; i++) {
if (key.equals(list.get(i).getKey())) {
@@ -9888,29 +9883,6 @@ public class NotificationManagerService extends SystemService {
return null;
}
- /**
- * There may be multiple records that match your criteria. For instance if there have been
- * multiple notifications posted which are enqueued for the same pkg, tag, id, userId. This
- * method will find all of them in the given list
- * @return
- */
- @GuardedBy("mNotificationLock")
- private List<NotificationRecord> findEnqueuedNotificationsForCriteria(
- String pkg, String tag, int id, int userId) {
- final ArrayList<NotificationRecord> records = new ArrayList<>();
- final int n = mEnqueuedNotifications.size();
- for (int i = 0; i < n; i++) {
- NotificationRecord r = mEnqueuedNotifications.get(i);
- if (notificationMatchesUserId(r, userId)
- && r.getSbn().getId() == id
- && TextUtils.equals(r.getSbn().getTag(), tag)
- && r.getSbn().getPackageName().equals(pkg)) {
- records.add(r);
- }
- }
- return records;
- }
-
@GuardedBy("mNotificationLock")
int indexOfNotificationLocked(String key) {
final int N = mNotificationList.size();
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index ffe33a832ce4..e960f4ba11fd 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -16,23 +16,16 @@
package com.android.server.notification;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-
import android.app.Notification;
-import android.content.ContentValues;
import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteFullException;
-import android.database.sqlite.SQLiteOpenHelper;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.server.notification.NotificationManagerService.DumpFilter;
@@ -42,8 +35,6 @@ import org.json.JSONObject;
import java.io.PrintWriter;
import java.util.ArrayDeque;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -63,7 +54,6 @@ public class NotificationUsageStats {
private static final String TAG = "NotificationUsageStats";
private static final boolean ENABLE_AGGREGATED_IN_MEMORY_STATS = true;
- private static final boolean ENABLE_SQLITE_LOG = true;
private static final AggregatedStats[] EMPTY_AGGREGATED_STATS = new AggregatedStats[0];
private static final String DEVICE_GLOBAL_STATS = "__global"; // packages start with letters
private static final int MSG_EMIT = 1;
@@ -73,12 +63,15 @@ public class NotificationUsageStats {
public static final int FOUR_HOURS = 1000 * 60 * 60 * 4;
private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : FOUR_HOURS;
- // Guarded by synchronized(this).
+ @GuardedBy("this")
private final Map<String, AggregatedStats> mStats = new HashMap<>();
+ @GuardedBy("this")
private final ArrayDeque<AggregatedStats[]> mStatsArrays = new ArrayDeque<>();
+ @GuardedBy("this")
private ArraySet<String> mStatExpiredkeys = new ArraySet<>();
private final Context mContext;
private final Handler mHandler;
+ @GuardedBy("this")
private long mLastEmitTime;
public NotificationUsageStats(Context context) {
@@ -105,11 +98,7 @@ public class NotificationUsageStats {
*/
public synchronized float getAppEnqueueRate(String packageName) {
AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
- if (stats != null) {
- return stats.getEnqueueRate(SystemClock.elapsedRealtime());
- } else {
- return 0f;
- }
+ return stats.getEnqueueRate(SystemClock.elapsedRealtime());
}
/**
@@ -117,11 +106,7 @@ public class NotificationUsageStats {
*/
public synchronized boolean isAlertRateLimited(String packageName) {
AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
- if (stats != null) {
- return stats.isAlertRateLimited();
- } else {
- return false;
- }
+ return stats.isAlertRateLimited();
}
/**
@@ -136,16 +121,32 @@ public class NotificationUsageStats {
}
/**
+ * Called when a notification that was enqueued by an app is effectively enqueued to be
+ * posted. This is after rate checking, to update the rate.
+ *
+ * <p>Note that if we updated the arrival estimate <em>before</em> checking it, then an app
+ * enqueueing at slightly above the acceptable rate would never get their notifications
+ * accepted; updating afterwards allows the rate to dip below the threshold and thus lets
+ * through some of them.
+ */
+ public synchronized void registerEnqueuedByAppAndAccepted(String packageName) {
+ final long now = SystemClock.elapsedRealtime();
+ AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(packageName);
+ for (AggregatedStats stats : aggregatedStatsArray) {
+ stats.updateInterarrivalEstimate(now);
+ }
+ releaseAggregatedStatsLocked(aggregatedStatsArray);
+ }
+
+ /**
* Called when a notification has been posted.
*/
public synchronized void registerPostedByApp(NotificationRecord notification) {
- final long now = SystemClock.elapsedRealtime();
- notification.stats.posttimeElapsedMs = now;
+ notification.stats.posttimeElapsedMs = SystemClock.elapsedRealtime();
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
for (AggregatedStats stats : aggregatedStatsArray) {
stats.numPostedByApp++;
- stats.updateInterarrivalEstimate(now);
stats.countApiUse(notification);
stats.numUndecoratedRemoteViews += (notification.hasUndecoratedRemoteView() ? 1 : 0);
}
@@ -161,7 +162,6 @@ public class NotificationUsageStats {
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
for (AggregatedStats stats : aggregatedStatsArray) {
stats.numUpdatedByApp++;
- stats.updateInterarrivalEstimate(SystemClock.elapsedRealtime());
stats.countApiUse(notification);
}
releaseAggregatedStatsLocked(aggregatedStatsArray);
@@ -257,12 +257,12 @@ public class NotificationUsageStats {
}
}
- // Locked by this.
+ @GuardedBy("this")
private AggregatedStats[] getAggregatedStatsLocked(NotificationRecord record) {
return getAggregatedStatsLocked(record.getSbn().getPackageName());
}
- // Locked by this.
+ @GuardedBy("this")
private AggregatedStats[] getAggregatedStatsLocked(String packageName) {
if (!ENABLE_AGGREGATED_IN_MEMORY_STATS) {
return EMPTY_AGGREGATED_STATS;
@@ -277,7 +277,7 @@ public class NotificationUsageStats {
return array;
}
- // Locked by this.
+ @GuardedBy("this")
private void releaseAggregatedStatsLocked(AggregatedStats[] array) {
for(int i = 0; i < array.length; i++) {
array[i] = null;
@@ -285,7 +285,7 @@ public class NotificationUsageStats {
mStatsArrays.offer(array);
}
- // Locked by this.
+ @GuardedBy("this")
private AggregatedStats getOrCreateAggregatedStatsLocked(String key) {
AggregatedStats result = mStats.get(key);
if (result == null) {
diff --git a/services/core/java/com/android/server/notification/RateEstimator.java b/services/core/java/com/android/server/notification/RateEstimator.java
index a2f93dce2bca..19768a286fd9 100644
--- a/services/core/java/com/android/server/notification/RateEstimator.java
+++ b/services/core/java/com/android/server/notification/RateEstimator.java
@@ -22,9 +22,10 @@ package com.android.server.notification;
*
* {@hide}
*/
-public class RateEstimator {
- private static final double RATE_ALPHA = 0.8;
+class RateEstimator {
+ private static final double RATE_ALPHA = 0.5;
private static final double MINIMUM_DT = 0.0005;
+
private Long mLastEventTime;
private double mInterarrivalTime;
@@ -34,18 +35,12 @@ public class RateEstimator {
}
/** Update the estimate to account for an event that just happened. */
- public float update(long now) {
- float rate;
- if (mLastEventTime == null) {
- // No last event time, rate is zero.
- rate = 0f;
- } else {
+ public void update(long now) {
+ if (mLastEventTime != null) {
// Calculate the new inter-arrival time based on last event time.
mInterarrivalTime = getInterarrivalEstimate(now);
- rate = (float) (1.0 / mInterarrivalTime);
}
mLastEventTime = now;
- return rate;
}
/** @return the estimated rate if there were a new event right now. */
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index a3866caacf39..abfc1d7ff2d2 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2342,6 +2342,11 @@ public class ComputerEngine implements Computer {
Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck, @PackageManager.ResolveInfoFlagsBits long flags) {
final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
+ var debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
+ if (debug) {
+ Slog.d(TAG, "Checking if instant app resolution allowed, resolvedActivities = "
+ + resolvedActivities);
+ }
for (int n = 0; n < count; n++) {
final ResolveInfo info = resolvedActivities.get(n);
final String packageName = info.activityInfo.packageName;
@@ -2365,6 +2370,8 @@ public class ComputerEngine implements Computer {
}
return false;
}
+ } else if (debug) {
+ Slog.d(TAG, "Could not find package " + packageName);
}
}
// We've exhausted all ways to deny ephemeral application; let the system look for them.
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index 811d6e272292..11f62e953525 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -788,7 +788,7 @@ public class DomainVerificationService extends SystemService
/**
* @param includeNegative See
- * {@link #approvalLevelForDomain(PackageStateInternal, String, boolean, int, Object)}.
+ * {@link #approvalLevelForDomain(PackageStateInternal, String, boolean, int, boolean, Object)}.
* @return Mapping of approval level to packages; packages are sorted by firstInstallTime. Null
* if no owners were found.
*/
@@ -808,7 +808,7 @@ public class DomainVerificationService extends SystemService
}
int level = approvalLevelForDomain(pkgSetting, domain, includeNegative, userId,
- domain);
+ DEBUG_APPROVAL, domain);
if (!includeNegative && level <= APPROVAL_LEVEL_NONE) {
continue;
}
@@ -1616,7 +1616,8 @@ public class DomainVerificationService extends SystemService
fillInfoMapForSamePackage(inputMap, packageName, APPROVAL_LEVEL_NONE);
continue;
}
- int approval = approvalLevelForDomain(pkgSetting, domain, false, userId, domain);
+ int approval = approvalLevelForDomain(pkgSetting, domain, false, userId, DEBUG_APPROVAL,
+ domain);
highestApproval = Math.max(highestApproval, approval);
fillInfoMapForSamePackage(inputMap, packageName, approval);
}
@@ -1726,15 +1727,21 @@ public class DomainVerificationService extends SystemService
@NonNull Intent intent, @PackageManager.ResolveInfoFlagsBits long resolveInfoFlags,
@UserIdInt int userId) {
String packageName = pkgSetting.getPackageName();
+ var debug = DEBUG_APPROVAL || (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, intent, userId, false, "not valid intent");
}
return APPROVAL_LEVEL_NONE;
}
- return approvalLevelForDomain(pkgSetting, intent.getData().getHost(), false, userId,
- intent);
+ var approvalLevel = approvalLevelForDomain(pkgSetting, intent.getData().getHost(), false,
+ userId, debug, intent);
+ if (debug) {
+ Slog.d(TAG + "Approval", "Final approval level for " + pkgSetting.getPackageName()
+ + " for host " + intent.getData().getHost() + " is " + approvalLevel);
+ }
+ return approvalLevel;
}
/**
@@ -1744,10 +1751,10 @@ public class DomainVerificationService extends SystemService
* {@link String} otherwise.
*/
private int approvalLevelForDomain(@NonNull PackageStateInternal pkgSetting,
- @NonNull String host, boolean includeNegative, @UserIdInt int userId,
+ @NonNull String host, boolean includeNegative, @UserIdInt int userId, boolean debug,
@NonNull Object debugObject) {
int approvalLevel = approvalLevelForDomainInternal(pkgSetting, host, includeNegative,
- userId, debugObject);
+ userId, debug, debugObject);
if (includeNegative && approvalLevel == APPROVAL_LEVEL_NONE) {
PackageUserStateInternal pkgUserState = pkgSetting.getUserStateOrDefault(userId);
if (!pkgUserState.isInstalled()) {
@@ -1768,13 +1775,13 @@ public class DomainVerificationService extends SystemService
}
private int approvalLevelForDomainInternal(@NonNull PackageStateInternal pkgSetting,
- @NonNull String host, boolean includeNegative, @UserIdInt int userId,
+ @NonNull String host, boolean includeNegative, @UserIdInt int userId, boolean debug,
@NonNull Object debugObject) {
String packageName = pkgSetting.getPackageName();
final AndroidPackage pkg = pkgSetting.getPkg();
if (pkg != null && includeNegative && !mCollector.containsWebDomain(pkg, host)) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"domain not declared");
}
@@ -1783,7 +1790,7 @@ public class DomainVerificationService extends SystemService
final PackageUserStateInternal pkgUserState = pkgSetting.getUserStates().get(userId);
if (pkgUserState == null) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"PackageUserState unavailable");
}
@@ -1791,7 +1798,7 @@ public class DomainVerificationService extends SystemService
}
if (!pkgUserState.isInstalled()) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"package not installed for user");
}
@@ -1799,7 +1806,7 @@ public class DomainVerificationService extends SystemService
}
if (!PackageUserStateUtils.isPackageEnabled(pkgUserState, pkg)) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"package not enabled for user");
}
@@ -1807,7 +1814,7 @@ public class DomainVerificationService extends SystemService
}
if (pkgUserState.isSuspended()) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"package suspended for user");
}
@@ -1834,7 +1841,7 @@ public class DomainVerificationService extends SystemService
synchronized (mLock) {
DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
if (pkgState == null) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false, "pkgState unavailable");
}
return APPROVAL_LEVEL_NONE;
@@ -1843,7 +1850,7 @@ public class DomainVerificationService extends SystemService
DomainVerificationInternalUserState userState = pkgState.getUserState(userId);
if (userState != null && !userState.isLinkHandlingAllowed()) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false,
"link handling not allowed");
}
@@ -1865,7 +1872,7 @@ public class DomainVerificationService extends SystemService
// Check if the exact host matches
Integer state = stateMap.get(host);
if (state != null && DomainVerificationState.isVerified(state)) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, true,
"host verified exactly");
}
@@ -1881,7 +1888,7 @@ public class DomainVerificationService extends SystemService
String domain = stateMap.keyAt(index);
if (domain.startsWith("*.") && host.endsWith(domain.substring(2))) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, true,
"host verified by wildcard");
}
@@ -1891,7 +1898,7 @@ public class DomainVerificationService extends SystemService
// Check user state if available
if (userState == null) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false, "userState unavailable");
}
return APPROVAL_LEVEL_NONE;
@@ -1900,7 +1907,7 @@ public class DomainVerificationService extends SystemService
// See if the user has approved the exact host
ArraySet<String> enabledHosts = userState.getEnabledHosts();
if (enabledHosts.contains(host)) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, true,
"host enabled by user exactly");
}
@@ -1912,7 +1919,7 @@ public class DomainVerificationService extends SystemService
for (int index = 0; index < enabledHostsSize; index++) {
String domain = enabledHosts.valueAt(index);
if (domain.startsWith("*.") && host.endsWith(domain.substring(2))) {
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, true,
"host enabled by user through wildcard");
}
@@ -1920,7 +1927,7 @@ public class DomainVerificationService extends SystemService
}
}
- if (DEBUG_APPROVAL) {
+ if (debug) {
debugApproval(packageName, debugObject, userId, false, "not approved");
}
return APPROVAL_LEVEL_NONE;
@@ -1948,7 +1955,7 @@ public class DomainVerificationService extends SystemService
}
int level = approvalLevelForDomain(pkgSetting, domain, includeNegative, userId,
- domain);
+ DEBUG_APPROVAL, domain);
if (level < minimumApproval) {
continue;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 56dcac8d122a..2806a1176e1c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -124,6 +124,7 @@ import android.hardware.hdmi.HdmiAudioSystemClient;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
+import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.AudioSystem;
@@ -205,6 +206,7 @@ import com.android.internal.policy.PhoneWindow;
import com.android.internal.policy.TransitionAnimation;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.AccessibilityManagerInternal;
import com.android.server.ExtconStateObserver;
@@ -215,6 +217,7 @@ import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
import com.android.server.display.BrightnessUtils;
import com.android.server.input.InputManagerInternal;
+import com.android.server.input.KeyboardMetricsCollector;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule;
@@ -678,6 +681,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_LAUNCH_ASSIST = 23;
private static final int MSG_RINGER_TOGGLE_CHORD = 24;
private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 25;
+ private static final int MSG_LOG_KEYBOARD_SYSTEM_EVENT = 26;
private class PolicyHandler extends Handler {
@Override
@@ -751,6 +755,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MSG_SWITCH_KEYBOARD_LAYOUT:
handleSwitchKeyboardLayout(msg.arg1, msg.arg2);
break;
+ case MSG_LOG_KEYBOARD_SYSTEM_EVENT:
+ handleKeyboardSystemEvent(msg.arg2, (KeyEvent) msg.obj);
+ break;
}
}
}
@@ -1088,6 +1095,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
if (dreamManagerInternal == null || !dreamManagerInternal.canStartDreaming(isScreenOn)) {
+ Slog.d(TAG, "Can't start dreaming when attempting to dream from short power"
+ + " press (isScreenOn=" + isScreenOn + ")");
noDreamAction.run();
return;
}
@@ -2288,6 +2297,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
cancelPendingScreenshotChordAction();
}
});
+
if (mHasFeatureWatch) {
mKeyCombinationManager.addRule(
new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) {
@@ -2907,7 +2917,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
};
+ /**
+ * Log the keyboard shortcuts without blocking the current thread.
+ *
+ * We won't log keyboard events when the input device is null
+ * or when it is virtual.
+ */
+ private void handleKeyboardSystemEvent(int keyboardSystemEvent, KeyEvent event) {
+ final InputManager inputManager = mContext.getSystemService(InputManager.class);
+ final InputDevice inputDevice = inputManager != null
+ ? inputManager.getInputDevice(event.getDeviceId()) : null;
+ if (inputDevice != null && !inputDevice.isVirtual()) {
+ KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(
+ inputDevice, keyboardSystemEvent,
+ new int[]{event.getKeyCode()}, event.getMetaState());
+ }
+ }
+
+ private void logKeyboardSystemsEvent(KeyEvent event, int keyboardSystemEvent) {
+ mHandler.obtainMessage(MSG_LOG_KEYBOARD_SYSTEM_EVENT, 0, keyboardSystemEvent, event)
+ .sendToTarget();
+ }
+
// TODO(b/117479243): handle it in InputPolicy
+ // TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring
/** {@inheritDoc} */
@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
@@ -2961,6 +2994,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
switch(keyCode) {
case KeyEvent.KEYCODE_HOME:
+ logKeyboardSystemsEvent(event, FrameworkStatsLog
+ .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME);
return handleHomeShortcuts(displayId, focusedToken, event);
case KeyEvent.KEYCODE_MENU:
// Hijack modified menu keys for debugging features
@@ -2978,6 +3013,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_RECENT_APPS:
if (down && repeatCount == 0) {
showRecentApps(false /* triggeredFromAltTab */);
+ logKeyboardSystemsEvent(event, FrameworkStatsLog
+ .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS);
}
return key_consumed;
case KeyEvent.KEYCODE_APP_SWITCH:
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 9bc0ee224ce0..a694e315ac29 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -265,7 +265,7 @@ public class Notifier {
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
- notifyWakeLockListener(callback, true);
+ notifyWakeLockListener(callback, tag, true);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -392,7 +392,7 @@ public class Notifier {
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
- notifyWakeLockListener(callback, false);
+ notifyWakeLockListener(callback, tag, false);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -1011,13 +1011,13 @@ public class Notifier {
return enabled && dndOff;
}
- private void notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled) {
+ private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) {
if (callback != null) {
mHandler.post(() -> {
try {
callback.onStateChanged(isEnabled);
} catch (RemoteException e) {
- throw new IllegalArgumentException("Wakelock.mCallback is already dead.", e);
+ Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e);
}
});
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index e82521584731..9128974fa9d3 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -1004,7 +1004,8 @@ public class StatsPullAtomService extends SystemService {
}
private void initAndRegisterDeferredPullers() {
- mUwbManager = mContext.getSystemService(UwbManager.class);
+ mUwbManager = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
+ ? mContext.getSystemService(UwbManager.class) : null;
registerUwbActivityInfo();
}
@@ -2172,6 +2173,9 @@ public class StatsPullAtomService extends SystemService {
}
private void registerUwbActivityInfo() {
+ if (mUwbManager == null) {
+ return;
+ }
int tagId = FrameworkStatsLog.UWB_ACTIVITY_INFO;
mStatsManager.setPullAtomCallback(
tagId,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 3e498d7d14ee..1133dba27ace 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -87,7 +87,7 @@ class WallpaperDataParser {
mImageWallpaper = ComponentName.unflattenFromString(
context.getResources().getString(R.string.image_wallpaper_component));
mIsLockscreenLiveWallpaperEnabled =
- SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", false);
+ SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true);
}
private JournaledFile makeJournaledFile(int userId) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 9add53751e2f..54eda55870de 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -82,6 +82,7 @@ import android.os.IBinder;
import android.os.IInterface;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -1603,7 +1604,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
mWallpaperCropper);
mIsLockscreenLiveWallpaperEnabled =
- SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", false);
+ SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true);
mIsMultiCropEnabled =
SystemProperties.getBoolean("persist.wm.debug.wallpaper_multi_crop", false);
LocalServices.addService(WallpaperManagerInternal.class, new LocalService());
@@ -2514,6 +2515,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
* Propagate a wake event to the wallpaper engine(s).
*/
public void notifyWakingUp(int x, int y, @NonNull Bundle extras) {
+ checkCallerIsSystemOrSystemUi();
synchronized (mLock) {
if (mIsLockscreenLiveWallpaperEnabled) {
for (WallpaperData data : getActiveWallpapers()) {
@@ -2551,6 +2553,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
* Propagate a sleep event to the wallpaper engine(s).
*/
public void notifyGoingToSleep(int x, int y, @NonNull Bundle extras) {
+ checkCallerIsSystemOrSystemUi();
synchronized (mLock) {
if (mIsLockscreenLiveWallpaperEnabled) {
for (WallpaperData data : getActiveWallpapers()) {
@@ -3684,6 +3687,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
mActivityManager.getPackageImportance(callingPackage) == IMPORTANCE_FOREGROUND);
}
+ /** Check that the caller is either system_server or systemui */
+ private void checkCallerIsSystemOrSystemUi() {
+ if (Binder.getCallingUid() != Process.myUid() && mContext.checkCallingPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE) != PERMISSION_GRANTED) {
+ throw new SecurityException("Access denied: only system processes can call this");
+ }
+ }
+
/**
* Certain user types do not support wallpapers (e.g. managed profiles). The check is
* implemented through through the OP_WRITE_WALLPAPER AppOp.
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 5c929a93bf12..bd07622ee5ca 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -30,6 +30,7 @@ import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
import android.hardware.HardwareBuffer;
+import android.os.SystemClock;
import android.os.Trace;
import android.util.Pair;
import android.util.Slog;
@@ -213,6 +214,7 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
// Failed to acquire image. Has been logged.
return null;
}
+ builder.setCaptureTime(SystemClock.elapsedRealtimeNanos());
builder.setSnapshot(screenshotBuffer.getHardwareBuffer());
builder.setColorSpace(screenshotBuffer.getColorSpace());
return builder.build();
@@ -432,6 +434,7 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
// color above
return new TaskSnapshot(
System.currentTimeMillis() /* id */,
+ SystemClock.elapsedRealtimeNanos() /* captureTime */,
topActivity.mActivityComponent, hwBitmap.getHardwareBuffer(),
hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,
mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3db031510317..2b2100e56f44 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5630,11 +5630,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
setClientVisible(visible);
}
+ final DisplayContent displayContent = getDisplayContent();
if (!visible) {
mImeInsetsFrozenUntilStartInput = true;
+ if (usingShellTransitions) {
+ final WindowState wallpaperTarget =
+ displayContent.mWallpaperController.getWallpaperTarget();
+ if (wallpaperTarget != null && wallpaperTarget.mActivityRecord == this) {
+ displayContent.mWallpaperController.hideWallpapers(wallpaperTarget);
+ }
+ }
}
- final DisplayContent displayContent = getDisplayContent();
if (!displayContent.mClosingApps.contains(this)
&& !displayContent.mOpeningApps.contains(this)
&& !fromTransition) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 3e3eb570d0e3..53a4752ba8a1 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1821,7 +1821,8 @@ class ActivityStarter {
// If Activity's launching into PiP, move the mStartActivity immediately to pinned mode.
// Note that mStartActivity and source should be in the same Task at this point.
if (mOptions != null && mOptions.isLaunchIntoPip()
- && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()) {
+ && sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
+ && balCode != BAL_BLOCK) {
mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
sourceRecord, "launch-into-pip");
}
@@ -2925,15 +2926,6 @@ class ActivityStarter {
}
}
- // If the matching task is already in the adjacent task of the launch target. Adjust to use
- // the adjacent task as its launch target. So the existing task will be launched into the
- // closer one and won't be reparent redundantly.
- final Task adjacentTargetTask = mTargetRootTask.getAdjacentTask();
- if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)
- && intentTask.isOnTop()) {
- mTargetRootTask = adjacentTargetTask;
- }
-
// If the target task is not in the front, then we need to bring it to the front...
// except... well, with SINGLE_TASK_LAUNCH it's not entirely clear. We'd like to have
// the same behavior as if a new instance was being started, which means not bringing it
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index e07c65426278..32f1f42aacb9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -262,9 +262,17 @@ public abstract class ActivityTaskManagerInternal {
*/
public abstract void setVr2dDisplayId(int vr2dDisplayId);
+ /**
+ * Registers a {@link ScreenObserver}.
+ */
public abstract void registerScreenObserver(ScreenObserver observer);
/**
+ * Unregisters the given {@link ScreenObserver}.
+ */
+ public abstract void unregisterScreenObserver(ScreenObserver observer);
+
+ /**
* Returns is the caller has the same uid as the Recents component
*/
public abstract boolean isCallerRecents(int callingUid);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 750ed986f567..a650d7709b67 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -296,6 +296,7 @@ import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -652,7 +653,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
*/
float mMinPercentageMultiWindowSupportWidth;
- final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
+ final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers =
+ Collections.synchronizedList(new ArrayList<>());
// VR Vr2d Display Id.
int mVr2dDisplayId = INVALID_DISPLAY;
@@ -3558,10 +3560,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mRootWindowContainer.forAllDisplays(displayContent -> {
mKeyguardController.keyguardGoingAway(displayContent.getDisplayId(), flags);
});
- WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
- if (wallpaperManagerInternal != null) {
- wallpaperManagerInternal.onKeyguardGoingAway();
- }
+ }
+ WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
+ if (wallpaperManagerInternal != null) {
+ wallpaperManagerInternal.onKeyguardGoingAway();
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -3649,6 +3651,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
return;
}
+ EventLogTags.writeWmEnterPip(r.mUserId, System.identityHashCode(r),
+ r.shortComponentName, Boolean.toString(isAutoEnter));
r.setPictureInPictureParams(params);
r.mAutoEnteringPip = isAutoEnter;
mRootWindowContainer.moveActivityToPinnedRootTask(r,
@@ -5867,6 +5871,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
+ public void unregisterScreenObserver(ScreenObserver observer) {
+ mScreenObservers.remove(observer);
+ }
+
+ @Override
public boolean isCallerRecents(int callingUid) {
return ActivityTaskManagerService.this.isCallerRecents(callingUid);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 0171c200b56c..3c976725cfee 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -2367,6 +2367,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityRecord prevTopActivity = mTopResumedActivity;
final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) {
+ if (topRootTask == null) {
+ // There's no focused task and there won't have any resumed activity either.
+ scheduleTopResumedActivityStateLossIfNeeded();
+ }
if (mService.isSleepingLocked()) {
// There won't be a next resumed activity. The top process should still be updated
// according to the current top focused activity.
@@ -2376,16 +2380,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
// Ask previous activity to release the top state.
- final boolean prevActivityReceivedTopState =
- prevTopActivity != null && !mTopResumedActivityWaitingForPrev;
- // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
- // before the prevTopActivity one hasn't reported back yet. So server never sent the top
- // resumed state change message to prevTopActivity.
- if (prevActivityReceivedTopState
- && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
- scheduleTopResumedStateLossTimeout(prevTopActivity);
- mTopResumedActivityWaitingForPrev = true;
- }
+ scheduleTopResumedActivityStateLossIfNeeded();
// Update the current top activity.
mTopResumedActivity = topRootTask.getTopResumedActivity();
@@ -2410,6 +2405,23 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mService.updateTopApp(mTopResumedActivity);
}
+ /** Schedule current top resumed activity state loss */
+ private void scheduleTopResumedActivityStateLossIfNeeded() {
+ if (mTopResumedActivity == null) {
+ return;
+ }
+
+ // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
+ // before the prevTopActivity one hasn't reported back yet. So server never sent the top
+ // resumed state change message to prevTopActivity.
+ if (!mTopResumedActivityWaitingForPrev
+ && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
+ scheduleTopResumedStateLossTimeout(mTopResumedActivity);
+ mTopResumedActivityWaitingForPrev = true;
+ mTopResumedActivity = null;
+ }
+ }
+
/** Schedule top resumed state change if previous top activity already reported back. */
private void scheduleTopResumedActivityStateIfNeeded() {
if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 2df601fd1d3b..b9f6e177e637 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -68,7 +68,7 @@ class AnrController {
void notifyAppUnresponsive(InputApplicationHandle applicationHandle,
TimeoutRecord timeoutRecord) {
try {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
+ timeoutRecord.mLatencyTracker.notifyAppUnresponsiveStarted();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowStarted();
preDumpIfLockTooSlow();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowEnded();
@@ -111,7 +111,6 @@ class AnrController {
if (!blamePendingFocusRequest) {
Slog.i(TAG_WM, "ANR in " + activity.getName() + ". Reason: "
+ timeoutRecord.mReason);
- dumpAnrStateAsync(activity, null /* windowState */, timeoutRecord.mReason);
mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
}
}
@@ -123,8 +122,13 @@ class AnrController {
} else {
activity.inputDispatchingTimedOut(timeoutRecord, INVALID_PID);
}
+
+ if (!blamePendingFocusRequest) {
+ dumpAnrStateAsync(activity, null /* windowState */, timeoutRecord.mReason);
+ }
+
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ timeoutRecord.mLatencyTracker.notifyAppUnresponsiveEnded();
}
}
@@ -139,7 +143,7 @@ class AnrController {
void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
@NonNull TimeoutRecord timeoutRecord) {
try {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyWindowUnresponsive()");
+ timeoutRecord.mLatencyTracker.notifyWindowUnresponsiveStarted();
if (notifyWindowUnresponsive(token, timeoutRecord)) {
return;
}
@@ -150,7 +154,7 @@ class AnrController {
}
notifyWindowUnresponsive(pid.getAsInt(), timeoutRecord);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ timeoutRecord.mLatencyTracker.notifyWindowUnresponsiveEnded();
}
}
@@ -168,6 +172,7 @@ class AnrController {
final int pid;
final boolean aboveSystem;
final ActivityRecord activity;
+ final WindowState windowState;
timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
synchronized (mService.mGlobalLock) {
timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
@@ -175,7 +180,7 @@ class AnrController {
if (target == null) {
return false;
}
- WindowState windowState = target.getWindowState();
+ windowState = target.getWindowState();
pid = target.getPid();
// Blame the activity if the input token belongs to the window. If the target is
// embedded, then we will blame the pid instead.
@@ -183,13 +188,13 @@ class AnrController {
? windowState.mActivityRecord : null;
Slog.i(TAG_WM, "ANR in " + target + ". Reason:" + timeoutRecord.mReason);
aboveSystem = isWindowAboveSystem(windowState);
- dumpAnrStateAsync(activity, windowState, timeoutRecord.mReason);
}
if (activity != null) {
activity.inputDispatchingTimedOut(timeoutRecord, pid);
} else {
mService.mAmInternal.inputDispatchingTimedOut(pid, aboveSystem, timeoutRecord);
}
+ dumpAnrStateAsync(activity, windowState, timeoutRecord.mReason);
return true;
}
@@ -199,15 +204,10 @@ class AnrController {
private void notifyWindowUnresponsive(int pid, TimeoutRecord timeoutRecord) {
Slog.i(TAG_WM,
"ANR in input window owned by pid=" + pid + ". Reason: " + timeoutRecord.mReason);
- timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
- synchronized (mService.mGlobalLock) {
- timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
- dumpAnrStateAsync(null /* activity */, null /* windowState */, timeoutRecord.mReason);
- }
-
// We cannot determine the z-order of the window, so place the anr dialog as high
// as possible.
mService.mAmInternal.inputDispatchingTimedOut(pid, true /*aboveSystem*/, timeoutRecord);
+ dumpAnrStateAsync(null /* activity */, null /* windowState */, timeoutRecord.mReason);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppSnapshotLoader.java b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
index 88c47526869f..ed65a2b2f8e6 100644
--- a/services/core/java/com/android/server/wm/AppSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
@@ -28,6 +28,7 @@ import android.graphics.BitmapFactory.Options;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
+import android.os.SystemClock;
import android.util.Slog;
import android.window.TaskSnapshot;
@@ -195,8 +196,9 @@ class AppSnapshotLoader {
taskSize = new Point(proto.taskWidth, proto.taskHeight);
}
- return new TaskSnapshot(proto.id, topActivityComponent, buffer,
- hwBitmap.getColorSpace(), proto.orientation, proto.rotation, taskSize,
+ return new TaskSnapshot(proto.id, SystemClock.elapsedRealtimeNanos(),
+ topActivityComponent, buffer, hwBitmap.getColorSpace(),
+ proto.orientation, proto.rotation, taskSize,
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
new Rect(proto.letterboxInsetLeft, proto.letterboxInsetTop,
proto.letterboxInsetRight, proto.letterboxInsetBottom),
diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java
index d22c38e39799..123a74dbf597 100644
--- a/services/core/java/com/android/server/wm/AppWarnings.java
+++ b/services/core/java/com/android/server/wm/AppWarnings.java
@@ -28,11 +28,13 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemProperties;
import android.util.AtomicFile;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.Xml;
+import com.android.internal.util.ArrayUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -56,6 +58,7 @@ class AppWarnings {
public static final int FLAG_HIDE_DISPLAY_SIZE = 0x01;
public static final int FLAG_HIDE_COMPILE_SDK = 0x02;
public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04;
+ public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08;
private final HashMap<String, Integer> mPackageFlags = new HashMap<>();
@@ -68,6 +71,7 @@ class AppWarnings {
private UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
private UnsupportedCompileSdkDialog mUnsupportedCompileSdkDialog;
private DeprecatedTargetSdkVersionDialog mDeprecatedTargetSdkVersionDialog;
+ private DeprecatedAbiDialog mDeprecatedAbiDialog;
/** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
private HashSet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities =
@@ -166,6 +170,31 @@ class AppWarnings {
}
/**
+ * Shows the "deprecated abi" warning, if necessary. This can only happen is the device
+ * supports both 64-bit and 32-bit ABIs, and the app only contains 32-bit libraries. The app
+ * cannot be installed if the device only supports 64-bit ABI while the app contains only 32-bit
+ * libraries.
+ *
+ * @param r activity record for which the warning may be displayed
+ */
+ public void showDeprecatedAbiDialogIfNeeded(ActivityRecord r) {
+ final boolean disableDeprecatedAbiDialog = SystemProperties.getBoolean(
+ "debug.wm.disable_deprecated_abi_dialog", false);
+ if (disableDeprecatedAbiDialog) {
+ return;
+ }
+ final String appPrimaryAbi = r.info.applicationInfo.primaryCpuAbi;
+ final String appSecondaryAbi = r.info.applicationInfo.secondaryCpuAbi;
+ final boolean appContainsOnly32bitLibraries =
+ (appPrimaryAbi != null && appSecondaryAbi == null && !appPrimaryAbi.contains("64"));
+ final boolean is64BitDevice =
+ ArrayUtils.find(Build.SUPPORTED_ABIS, abi -> abi.contains("64")) != null;
+ if (is64BitDevice && appContainsOnly32bitLibraries) {
+ mUiHandler.showDeprecatedAbiDialog(r);
+ }
+ }
+
+ /**
* Called when an activity is being started.
*
* @param r record for the activity being started
@@ -174,6 +203,7 @@ class AppWarnings {
showUnsupportedCompileSdkDialogIfNeeded(r);
showUnsupportedDisplaySizeDialogIfNeeded(r);
showDeprecatedTargetDialogIfNeeded(r);
+ showDeprecatedAbiDialogIfNeeded(r);
}
/**
@@ -299,6 +329,27 @@ class AppWarnings {
}
/**
+ * Shows the "deprecated abi" warning for the given application.
+ * <p>
+ * <strong>Note:</strong> Must be called on the UI thread.
+ *
+ * @param ar record for the activity that triggered the warning
+ */
+ @UiThread
+ private void showDeprecatedAbiDialogUiThread(ActivityRecord ar) {
+ if (mDeprecatedAbiDialog != null) {
+ mDeprecatedAbiDialog.dismiss();
+ mDeprecatedAbiDialog = null;
+ }
+ if (ar != null && !hasPackageFlag(
+ ar.packageName, FLAG_HIDE_DEPRECATED_ABI)) {
+ mDeprecatedAbiDialog = new DeprecatedAbiDialog(
+ AppWarnings.this, mUiContext, ar.info.applicationInfo);
+ mDeprecatedAbiDialog.show();
+ }
+ }
+
+ /**
* Dismisses all warnings for the given package.
* <p>
* <strong>Note:</strong> Must be called on the UI thread.
@@ -328,6 +379,13 @@ class AppWarnings {
mDeprecatedTargetSdkVersionDialog.dismiss();
mDeprecatedTargetSdkVersionDialog = null;
}
+
+ // Hides the "deprecated abi" dialog if necessary.
+ if (mDeprecatedAbiDialog != null && (name == null || name.equals(
+ mDeprecatedAbiDialog.mPackageName))) {
+ mDeprecatedAbiDialog.dismiss();
+ mDeprecatedAbiDialog = null;
+ }
}
/**
@@ -381,6 +439,7 @@ class AppWarnings {
private static final int MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG = 3;
private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4;
private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5;
+ private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6;
public UiHandler(Looper looper) {
super(looper, null, true);
@@ -408,6 +467,10 @@ class AppWarnings {
final ActivityRecord ar = (ActivityRecord) msg.obj;
showDeprecatedTargetSdkDialogUiThread(ar);
} break;
+ case MSG_SHOW_DEPRECATED_ABI_DIALOG: {
+ final ActivityRecord ar = (ActivityRecord) msg.obj;
+ showDeprecatedAbiDialogUiThread(ar);
+ } break;
}
}
@@ -431,6 +494,11 @@ class AppWarnings {
obtainMessage(MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG, r).sendToTarget();
}
+ public void showDeprecatedAbiDialog(ActivityRecord r) {
+ removeMessages(MSG_SHOW_DEPRECATED_ABI_DIALOG);
+ obtainMessage(MSG_SHOW_DEPRECATED_ABI_DIALOG, r).sendToTarget();
+ }
+
public void hideDialogsForPackage(String name) {
obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, name).sendToTarget();
}
diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
index e88cfbf6986e..527edc13931a 100644
--- a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
+++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
@@ -190,6 +190,11 @@ class BackgroundLaunchProcessController {
return false;
}
List<IBinder> binderTokens = getOriginatingTokensThatAllowBal();
+ if (binderTokens.isEmpty()) {
+ // no tokens to allow anything
+ return false;
+ }
+
// The callback will decide.
return mBackgroundActivityStartCallback.isActivityStartAllowed(
binderTokens, uid, packageName);
diff --git a/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java
new file mode 100644
index 000000000000..e96208d3d0b3
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+
+class DeprecatedAbiDialog extends AppWarnings.BaseDialog {
+ DeprecatedAbiDialog(final AppWarnings manager, Context context,
+ ApplicationInfo appInfo) {
+ super(manager, appInfo.packageName);
+
+ final PackageManager pm = context.getPackageManager();
+ final CharSequence label = appInfo.loadSafeLabel(pm,
+ PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
+ PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE
+ | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
+ final CharSequence message = context.getString(R.string.deprecated_abi_message);
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setPositiveButton(R.string.ok, (dialog, which) ->
+ manager.setPackageFlag(
+ mPackageName, AppWarnings.FLAG_HIDE_DEPRECATED_ABI, true))
+ .setMessage(message)
+ .setTitle(label);
+
+ // Ensure the content view is prepared.
+ mDialog = builder.create();
+ mDialog.create();
+
+ final Window window = mDialog.getWindow();
+ window.setType(WindowManager.LayoutParams.TYPE_PHONE);
+
+ // DO NOT MODIFY. Used by CTS to verify the dialog is displayed.
+ window.getAttributes().setTitle("DeprecatedAbiDialog");
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 41c052d95053..31b1069dd022 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -19,9 +19,6 @@ package com.android.server.wm;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.content.Context;
-import android.hardware.devicestate.DeviceStateManager;
-import android.os.Handler;
-import android.os.HandlerExecutor;
import android.util.ArrayMap;
import com.android.internal.R;
@@ -36,17 +33,15 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * Class that registers callbacks with the {@link DeviceStateManager} and responds to device
+ * Class that listens for a callback from display manager and responds to device state
* changes.
*/
-final class DeviceStateController implements DeviceStateManager.DeviceStateCallback {
+final class DeviceStateController {
// Used to synchronize WindowManager services call paths with DeviceStateManager's callbacks.
@NonNull
private final WindowManagerGlobalLock mWmLock;
@NonNull
- private final DeviceStateManager mDeviceStateManager;
- @NonNull
private final int[] mOpenDeviceStates;
@NonNull
private final int[] mHalfFoldedDeviceStates;
@@ -77,10 +72,8 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
CONCURRENT,
}
- DeviceStateController(@NonNull Context context, @NonNull Handler handler,
- @NonNull WindowManagerGlobalLock wmLock) {
+ DeviceStateController(@NonNull Context context, @NonNull WindowManagerGlobalLock wmLock) {
mWmLock = wmLock;
- mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
mOpenDeviceStates = context.getResources()
.getIntArray(R.array.config_openDeviceStates);
@@ -97,10 +90,6 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
.getBoolean(R.bool
.config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);
-
- if (mDeviceStateManager != null) {
- mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this);
- }
}
/**
@@ -137,8 +126,19 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
return mMatchBuiltInDisplayOrientationToDefaultDisplay;
}
- @Override
- public void onStateChanged(int state) {
+ /**
+ * This event is sent from DisplayManager just before the device state is applied to
+ * the displays. This is needed to make sure that we first receive this callback before
+ * any device state related display updates from the DisplayManager.
+ *
+ * The flow for this event is the following:
+ * - {@link DeviceStateManager} sends event to {@link android.hardware.display.DisplayManager}
+ * - {@link android.hardware.display.DisplayManager} sends it to {@link WindowManagerInternal}
+ * - {@link WindowManagerInternal} eventually calls this method
+ *
+ * @param state device state as defined by {@link DeviceStateManager}
+ */
+ public void onDeviceStateReceivedByDisplayManager(int state) {
mCurrentState = state;
final DeviceState deviceState;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e44d27911262..6aec96988a77 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6511,6 +6511,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
.getKeyguardController().isDisplayOccluded(mDisplayId);
}
+ /**
+ * @return the task that is occluding the keyguard
+ */
+ @Nullable
+ Task getTaskOccludingKeyguard() {
+ final KeyguardController keyguardController = mRootWindowContainer.mTaskSupervisor
+ .getKeyguardController();
+ if (keyguardController.getTopOccludingActivity(mDisplayId) != null) {
+ return keyguardController.getTopOccludingActivity(mDisplayId).getRootTask();
+ }
+ if (keyguardController.getDismissKeyguardActivity(mDisplayId) != null) {
+ return keyguardController.getDismissKeyguardActivity(mDisplayId).getRootTask();
+ }
+ return null;
+ }
+
@VisibleForTesting
void removeAllTasks() {
forAllTasks((t) -> { t.getRootTask().removeChild(t, "removeAllTasks"); });
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index d0ca8e3ed3e7..dd62b21bc7d1 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -271,13 +271,13 @@ public class DisplayPolicy {
private WindowState mSystemUiControllingWindow;
// Candidate window to determine the color of navigation bar. The window needs to be top
- // fullscreen-app windows or dim layers that are intersecting with the window frame of status
- // bar.
+ // fullscreen-app windows or dim layers that are intersecting with the window frame of
+ // navigation bar.
private WindowState mNavBarColorWindowCandidate;
- // The window to determine opacity and background of translucent navigation bar. The window
- // needs to be opaque.
- private WindowState mNavBarBackgroundWindow;
+ // Candidate window to determine opacity and background of translucent navigation bar.
+ // The window frame must intersect the frame of navigation bar.
+ private WindowState mNavBarBackgroundWindowCandidate;
/**
* A collection of {@link AppearanceRegion} to indicate that which region of status bar applies
@@ -961,12 +961,6 @@ public class DisplayPolicy {
if (!win.mSession.mCanSetUnrestrictedGestureExclusion) {
attrs.privateFlags &= ~PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
}
-
- final InsetsSourceProvider provider = win.getControllableInsetProvider();
- if (provider != null && provider.getSource().insetsRoundedCornerFrame()
- != attrs.insetsRoundedCornerFrame) {
- provider.getSource().setInsetsRoundedCornerFrame(attrs.insetsRoundedCornerFrame);
- }
}
/**
@@ -1104,9 +1098,11 @@ public class DisplayPolicy {
} else {
overrideProviders = null;
}
- mDisplayContent.getInsetsStateController().getOrCreateSourceProvider(
- provider.getId(), provider.getType()).setWindowContainer(
- win, frameProvider, overrideProviders);
+ final InsetsSourceProvider sourceProvider = mDisplayContent
+ .getInsetsStateController().getOrCreateSourceProvider(provider.getId(),
+ provider.getType());
+ sourceProvider.getSource().setFlags(provider.getFlags());
+ sourceProvider.setWindowContainer(win, frameProvider, overrideProviders);
mInsetsSourceWindowsExceptIme.add(win);
}
}
@@ -1387,7 +1383,7 @@ public class DisplayPolicy {
mBottomGestureHost = null;
mTopFullscreenOpaqueWindowState = null;
mNavBarColorWindowCandidate = null;
- mNavBarBackgroundWindow = null;
+ mNavBarBackgroundWindowCandidate = null;
mStatusBarAppearanceRegionList.clear();
mLetterboxDetails.clear();
mStatusBarBackgroundWindows.clear();
@@ -1514,8 +1510,8 @@ public class DisplayPolicy {
mNavBarColorWindowCandidate = win;
addSystemBarColorApp(win);
}
- if (mNavBarBackgroundWindow == null) {
- mNavBarBackgroundWindow = win;
+ if (mNavBarBackgroundWindowCandidate == null) {
+ mNavBarBackgroundWindowCandidate = win;
}
}
@@ -1539,12 +1535,19 @@ public class DisplayPolicy {
}
if (isOverlappingWithNavBar(win) && mNavBarColorWindowCandidate == null) {
mNavBarColorWindowCandidate = win;
+ addSystemBarColorApp(win);
}
- } else if (appWindow && attached == null && mNavBarColorWindowCandidate == null
+ } else if (appWindow && attached == null
+ && (mNavBarColorWindowCandidate == null || mNavBarBackgroundWindowCandidate == null)
&& win.getFrame().contains(
getBarContentFrameForWindow(win, Type.navigationBars()))) {
- mNavBarColorWindowCandidate = win;
- addSystemBarColorApp(win);
+ if (mNavBarColorWindowCandidate == null) {
+ mNavBarColorWindowCandidate = win;
+ addSystemBarColorApp(win);
+ }
+ if (mNavBarBackgroundWindowCandidate == null) {
+ mNavBarBackgroundWindowCandidate = win;
+ }
}
}
@@ -1854,6 +1857,9 @@ public class DisplayPolicy {
*/
final Rect mConfigFrame = new Rect();
+ /** The count of insets sources when calculating this info. */
+ int mLastInsetsSourceCount;
+
private boolean mNeedUpdate = true;
void update(DisplayContent dc, int rotation, int w, int h) {
@@ -1875,6 +1881,7 @@ public class DisplayPolicy {
mNonDecorFrame.inset(mNonDecorInsets);
mConfigFrame.set(displayFrame);
mConfigFrame.inset(mConfigInsets);
+ mLastInsetsSourceCount = dc.getDisplayPolicy().mInsetsSourceWindowsExceptIme.size();
mNeedUpdate = false;
}
@@ -1883,6 +1890,7 @@ public class DisplayPolicy {
mConfigInsets.set(other.mConfigInsets);
mNonDecorFrame.set(other.mNonDecorFrame);
mConfigFrame.set(other.mConfigFrame);
+ mLastInsetsSourceCount = other.mLastInsetsSourceCount;
mNeedUpdate = false;
}
@@ -1981,6 +1989,19 @@ public class DisplayPolicy {
newInfo.update(mDisplayContent, rotation, dw, dh);
final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
+ // Even if the config frame is not changed in current rotation, it may change the
+ // insets in other rotations if the source count is changed.
+ if (newInfo.mLastInsetsSourceCount != currentInfo.mLastInsetsSourceCount) {
+ for (int i = mDecorInsets.mInfoForRotation.length - 1; i >= 0; i--) {
+ if (i != rotation) {
+ final boolean flipSize = (i + rotation) % 2 == 1;
+ final int w = flipSize ? dh : dw;
+ final int h = flipSize ? dw : dh;
+ mDecorInsets.mInfoForRotation[i].update(mDisplayContent, i, w, h);
+ }
+ }
+ mDecorInsets.mInfoForRotation[rotation].set(newInfo);
+ }
return false;
}
if (mCachedDecorInsets != null && !mCachedDecorInsets.canPreserve()
@@ -2465,7 +2486,7 @@ public class DisplayPolicy {
return win.isFullyTransparentBarAllowed(getBarContentFrameForWindow(win, type));
}
- private boolean drawsBarBackground(WindowState win) {
+ private static boolean drawsBarBackground(WindowState win) {
if (win == null) {
return true;
}
@@ -2505,7 +2526,14 @@ public class DisplayPolicy {
*/
private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible,
boolean freeformRootTaskVisible) {
- final boolean drawBackground = drawsBarBackground(mNavBarBackgroundWindow);
+ final WindowState navBackgroundWin = chooseNavigationBackgroundWindow(
+ mNavBarBackgroundWindowCandidate,
+ mDisplayContent.mInputMethodWindow,
+ mNavigationBarPosition);
+ final boolean drawBackground = navBackgroundWin != null
+ // There is no app window showing underneath nav bar. (e.g., The screen is locked.)
+ // Let system windows (ex: notification shade) draw nav bar background.
+ || mNavBarBackgroundWindowCandidate == null;
if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
if (drawBackground) {
@@ -2525,7 +2553,7 @@ public class DisplayPolicy {
}
}
- if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, Type.navigationBars())) {
+ if (!isFullyTransparentAllowed(navBackgroundWin, Type.navigationBars())) {
appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
}
@@ -2536,6 +2564,20 @@ public class DisplayPolicy {
return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS;
}
+ @VisibleForTesting
+ @Nullable
+ static WindowState chooseNavigationBackgroundWindow(WindowState candidate,
+ WindowState imeWindow, @NavigationBarPosition int navBarPosition) {
+ if (imeWindow != null && imeWindow.isVisible() && navBarPosition == NAV_BAR_BOTTOM
+ && drawsBarBackground(imeWindow)) {
+ return imeWindow;
+ }
+ if (drawsBarBackground(candidate)) {
+ return candidate;
+ }
+ return null;
+ }
+
private boolean isImmersiveMode(WindowState win) {
if (win == null) {
return false;
@@ -2708,9 +2750,9 @@ public class DisplayPolicy {
pw.print(prefix); pw.print("mNavBarColorWindowCandidate=");
pw.println(mNavBarColorWindowCandidate);
}
- if (mNavBarBackgroundWindow != null) {
- pw.print(prefix); pw.print("mNavBarBackgroundWindow=");
- pw.println(mNavBarBackgroundWindow);
+ if (mNavBarBackgroundWindowCandidate != null) {
+ pw.print(prefix); pw.print("mNavBarBackgroundWindowCandidate=");
+ pw.println(mNavBarBackgroundWindowCandidate);
}
if (mLastStatusBarAppearanceRegions != null) {
pw.print(prefix); pw.println("mLastStatusBarAppearanceRegions=");
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 87de0f6e4aa0..8be36f07a040 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -513,6 +513,7 @@ public class DisplayRotation {
}
if (mDisplayContent.inTransition()
+ && mDisplayContent.getDisplayPolicy().isScreenOnFully()
&& !mDisplayContent.mTransitionController.useShellTransitionsRotation()) {
// Rotation updates cannot be performed while the previous rotation change animation
// is still in progress. Skip this update. We will try updating again after the
@@ -1729,7 +1730,9 @@ public class DisplayRotation {
}
/**
- * Called by the DeviceStateManager callback when the device state changes.
+ * Called by the display manager just before it applied the device state, it is guaranteed
+ * that in case of physical display change the {@link DisplayRotation#physicalDisplayChanged}
+ * method will be invoked *after* this one.
*/
void foldStateChanged(DeviceStateController.DeviceState deviceState) {
if (mFoldController != null) {
diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags
index 244656ca68e6..d957591ab7f9 100644
--- a/services/core/java/com/android/server/wm/EventLogTags.logtags
+++ b/services/core/java/com/android/server/wm/EventLogTags.logtags
@@ -80,3 +80,6 @@ option java_package com.android.server.wm
# Request surface flinger to show / hide the wallpaper surface.
33001 wm_wallpaper_surface (Display Id|1|5),(Visible|1),(Target|3)
+
+# Entering pip called
+38000 wm_enter_pip (User|1|5),(Token|1|5),(Component Name|3),(is Auto Enter|3)
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index ff2985c98421..e8a4c1c5c3d3 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -91,6 +91,21 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
}
@Override
+ void setClientVisible(boolean clientVisible) {
+ final boolean wasClientVisible = isClientVisible();
+ super.setClientVisible(clientVisible);
+ // The layer of ImePlaceholder needs to be updated on a higher z-order for
+ // non-activity window (For activity window, IME is already on top of it).
+ if (!wasClientVisible && isClientVisible()) {
+ final InsetsControlTarget imeControlTarget = getControlTarget();
+ if (imeControlTarget != null && imeControlTarget.getWindow() != null
+ && imeControlTarget.getWindow().mActivityRecord == null) {
+ mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
+ }
+ }
+ }
+
+ @Override
void setServerVisible(boolean serverVisible) {
mServerVisible = serverVisible;
if (!mFrozen) {
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index b7eaf259ea7a..21004ab8d75a 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -175,7 +175,7 @@ class InsetsSourceProvider {
if (windowContainer == null) {
setServerVisible(false);
mSource.setVisibleFrame(null);
- mSource.setInsetsRoundedCornerFrame(false);
+ mSource.setFlags(0, 0xffffffff);
mSourceFrame.setEmpty();
} else {
mWindowContainer.getInsetsSourceProviders().put(mSource.getId(), this);
@@ -272,15 +272,17 @@ class InsetsSourceProvider {
/** @return A new source computed by the specified window frame in the given display frames. */
InsetsSource createSimulatedSource(DisplayFrames displayFrames, Rect frame) {
- // Don't copy visible frame because it might not be calculated in the provided display
- // frames and it is not significant for this usage.
- final InsetsSource source = new InsetsSource(mSource.getId(), mSource.getType());
- source.setVisible(mSource.isVisible());
+ final InsetsSource source = new InsetsSource(mSource);
mTmpRect.set(frame);
if (mFrameProvider != null) {
mFrameProvider.apply(displayFrames, mWindowContainer, mTmpRect);
}
source.setFrame(mTmpRect);
+
+ // Don't copy visible frame because it might not be calculated in the provided display
+ // frames and it is not significant for this usage.
+ source.setVisibleFrame(null);
+
return source;
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 5f6d66011768..99878a3d0ffe 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
@@ -411,19 +410,20 @@ class KeyguardController {
if (waitAppTransition) {
mService.deferWindowLayout();
try {
- mRootWindowContainer.getDefaultDisplay()
- .requestTransitionAndLegacyPrepare(
- isDisplayOccluded(DEFAULT_DISPLAY)
- ? TRANSIT_KEYGUARD_OCCLUDE
- : TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */);
+ if (isDisplayOccluded(DEFAULT_DISPLAY)) {
+ mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
+ TRANSIT_KEYGUARD_OCCLUDE,
+ topActivity != null ? topActivity.getRootTask() : null);
+ } else {
+ mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
+ TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */);
+ }
updateKeyguardSleepToken(DEFAULT_DISPLAY);
mWindowManager.executeAppTransition();
} finally {
mService.continueWindowLayout();
}
}
- dismissMultiWindowModeForTaskIfNeeded(displayId, topActivity != null
- ? topActivity.getRootTask() : null);
}
/**
@@ -473,6 +473,14 @@ class KeyguardController {
return getDisplayState(displayId).mOccluded;
}
+ ActivityRecord getTopOccludingActivity(int displayId) {
+ return getDisplayState(displayId).mTopOccludesActivity;
+ }
+
+ ActivityRecord getDismissKeyguardActivity(int displayId) {
+ return getDisplayState(displayId).mDismissingKeyguardActivity;
+ }
+
/**
* @return true if Keyguard can be currently dismissed without entering credentials.
*/
@@ -488,22 +496,6 @@ class KeyguardController {
return getDisplayState(DEFAULT_DISPLAY).mShowingDream;
}
- private void dismissMultiWindowModeForTaskIfNeeded(int displayId,
- @Nullable Task currentTaskControllingOcclusion) {
- // TODO(b/113840485): Handle docked stack for individual display.
- if (!getDisplayState(displayId).mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) {
- return;
- }
-
- // Dismiss freeform windowing mode
- if (currentTaskControllingOcclusion == null) {
- return;
- }
- if (currentTaskControllingOcclusion.inFreeformWindowingMode()) {
- currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- }
- }
-
private void updateKeyguardSleepToken() {
for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
displayNdx >= 0; displayNdx--) {
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index d83c8612b9e9..c2439888db43 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1428,7 +1428,8 @@ final class LetterboxUiController {
for (int i = state.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = state.sourceAt(i);
if (source.getType() == WindowInsets.Type.navigationBars()
- && source.insetsRoundedCornerFrame() && source.isVisible()) {
+ && source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)
+ && source.isVisible()) {
return source;
}
}
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 78522498987c..f0757db76bda 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -71,7 +71,10 @@ public class PhysicalDisplaySwitchTransitionLauncher {
}
/**
- * Called by the DeviceStateManager callback when the state changes.
+ * Called by the display manager just before it applied the device state, it is guaranteed
+ * that in case of physical display change the
+ * {@link PhysicalDisplaySwitchTransitionLauncher#requestDisplaySwitchTransitionIfNeeded}
+ * method will be invoked *after* this one.
*/
void foldStateChanged(DeviceState newDeviceState) {
boolean isUnfolding = mDeviceState == FOLDED
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index e47787e97f20..9ef5ed051a13 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1104,6 +1104,10 @@ class RecentTasks {
// front unless overridden by the provided activity options
mTasks.remove(taskIndex);
mTasks.add(0, task);
+ if (taskIndex != 0) {
+ // Only notify when position changes
+ mTaskNotificationController.notifyTaskListUpdated();
+ }
if (DEBUG_RECENTS) {
Slog.d(TAG_RECENTS, "addRecent: moving to top " + task
@@ -1552,7 +1556,7 @@ class RecentTasks {
task.affinity != null && task.affinity.equals(t.affinity);
final boolean sameIntent = intent != null && intent.filterEquals(trIntent);
boolean multiTasksAllowed = false;
- final int flags = intent.getFlags();
+ final int flags = intent != null ? intent.getFlags() : 0;
if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0
&& (flags & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
multiTasksAllowed = true;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 536915929e88..4995236da1be 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -438,8 +438,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mTaskSupervisor = mService.mTaskSupervisor;
mTaskSupervisor.mRootWindowContainer = this;
mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
- mDeviceStateController = new DeviceStateController(service.mContext, service.mH,
- service.mGlobalLock);
+ mDeviceStateController = new DeviceStateController(service.mContext, service.mGlobalLock);
mDisplayRotationCoordinator = new DisplayRotationCoordinator();
}
@@ -1283,6 +1282,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
false /* includingParents */);
}
+ /**
+ * Called just before display manager has applied the device state to the displays
+ * @param deviceState device state as defined by
+ * {@link android.hardware.devicestate.DeviceStateManager}
+ */
+ void onDisplayManagerReceivedDeviceState(int deviceState) {
+ mDeviceStateController.onDeviceStateReceivedByDisplayManager(deviceState);
+ }
+
// TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
DisplayContent getDefaultDisplay() {
return mDefaultDisplay;
@@ -2376,6 +2384,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (!displayShouldSleep && display.mTransitionController.isShellTransitionsEnabled()
&& !display.mTransitionController.isCollecting()) {
int transit = TRANSIT_NONE;
+ Task startTask = null;
if (!display.getDisplayPolicy().isAwake()) {
// Note that currently this only happens on default display because non-default
// display is always awake.
@@ -2383,12 +2392,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
} else if (display.isKeyguardOccluded()) {
// The display was awake so this is resuming activity for occluding keyguard.
transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
+ startTask = display.getTaskOccludingKeyguard();
}
if (transit != TRANSIT_NONE) {
display.mTransitionController.requestStartTransition(
display.mTransitionController.createTransition(transit),
- null /* startTask */, null /* remoteTransition */,
- null /* displayChange */);
+ startTask, null /* remoteTransition */, null /* displayChange */);
}
}
// Set the sleeping state of the root tasks on the display.
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index afef85e34fe0..58e1c544202d 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -314,6 +314,11 @@ class SnapshotPersistQueue {
}
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 false;
+ }
final File file = mPersistInfoProvider.getHighResolutionBitmapFile(mId, mUserId);
try {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bb6f8056acda..1ae1e03a6c4a 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -49,6 +49,7 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
@@ -1271,6 +1272,10 @@ class Task extends TaskFragment {
if (isPersistable) {
mLastTimeMoved = System.currentTimeMillis();
}
+ if (toTop && inRecents) {
+ // If task is in recents, ensure it is at the top
+ mTaskSupervisor.mRecentTasks.add(this);
+ }
}
// Close up recents linked list.
@@ -1842,6 +1847,9 @@ class Task extends TaskFragment {
td.setEnsureStatusBarContrastWhenTransparent(
atd.getEnsureStatusBarContrastWhenTransparent());
}
+ if (td.getStatusBarAppearance() == 0) {
+ td.setStatusBarAppearance(atd.getStatusBarAppearance());
+ }
if (td.getNavigationBarColor() == 0) {
td.setNavigationBarColor(atd.getNavigationBarColor());
td.setEnsureNavigationBarContrastWhenTransparent(
@@ -2858,7 +2866,7 @@ class Task extends TaskFragment {
getDisplayContent().getInsetsStateController().getRawInsetsState();
for (int i = state.sourceSize() - 1; i >= 0; i--) {
final InsetsSource source = state.sourceAt(i);
- if (source.insetsRoundedCornerFrame()) {
+ if (source.hasFlags(FLAG_INSETS_ROUNDED_CORNER)) {
animationBounds.inset(source.calculateVisibleInsets(animationBounds));
}
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 7e20b3bbe396..c747c09a6872 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -180,6 +180,18 @@ class TaskSnapshotController extends AbsAppSnapshotController<Task, TaskSnapshot
}
/**
+ * Returns the elapsed real time (in nanoseconds) at which a snapshot for the given task was
+ * last taken, or -1 if no such snapshot exists for that task.
+ */
+ long getSnapshotCaptureTime(int taskId) {
+ final TaskSnapshot snapshot = mCache.getSnapshot(taskId);
+ if (snapshot != null) {
+ return snapshot.getCaptureTime();
+ }
+ return -1;
+ }
+
+ /**
* @see WindowManagerInternal#clearSnapshotCache
*/
public void clearSnapshotCache() {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 0ce794fdb2ba..b938b9e4ec51 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -687,7 +687,11 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// All windows are synced already.
return;
}
- if (!isInTransition(wc)) return;
+ if (wc.mDisplayContent == null || !isInTransition(wc)) return;
+ if (!wc.mDisplayContent.getDisplayPolicy().isScreenOnFully()
+ || wc.mDisplayContent.getDisplayInfo().state == Display.STATE_OFF) {
+ mFlags |= WindowManager.TRANSIT_FLAG_INVISIBLE;
+ }
if (mContainerFreezer == null) {
mContainerFreezer = new ScreenshotFreezer();
@@ -1086,12 +1090,23 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (commitVisibility) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
" Commit activity becoming invisible: %s", ar);
+ final SnapshotController snapController = mController.mSnapshotController;
if (mTransientLaunches != null && !task.isVisibleRequested()) {
+ final long startTimeNs = mLogger.mSendTimeNs;
+ final long lastSnapshotTimeNs = snapController.mTaskSnapshotController
+ .getSnapshotCaptureTime(task.mTaskId);
// If transition is transient, then snapshots are taken at end of
- // transition.
- mController.mSnapshotController.mTaskSnapshotController
- .recordSnapshot(task, false /* allowSnapshotHome */);
- mController.mSnapshotController.mActivitySnapshotController
+ // transition only if a snapshot was not already captured by request
+ // during the transition
+ if (lastSnapshotTimeNs < startTimeNs) {
+ snapController.mTaskSnapshotController
+ .recordSnapshot(task, false /* allowSnapshotHome */);
+ } else {
+ ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+ " Skipping post-transition snapshot for task %d",
+ task.mTaskId);
+ }
+ snapController.mActivitySnapshotController
.notifyAppVisibilityChanged(ar, false /* visible */);
}
ar.commitVisibility(false /* visible */, false /* performLayout */,
@@ -2234,8 +2249,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
while (leashReference.getParent() != ancestor) {
leashReference = leashReference.getParent();
}
+
final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName(
"Transition Root: " + leashReference.getName()).build();
+ rootLeash.setUnreleasedWarningCallSite("Transition.calculateTransitionRoots");
startT.setLayer(rootLeash, leashReference.getLastLayer());
outInfo.addRootLeash(endDisplayId, rootLeash,
ancestor.getBounds().left, ancestor.getBounds().top);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index edafe0606b13..64038355b1df 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -146,11 +146,10 @@ class WallpaperController {
}
} else {
final ActivityRecord ar = w.mActivityRecord;
- final TransitionController tc = w.mTransitionController;
// The animating window can still be visible on screen if it is in transition, so we
// should check whether this window can be wallpaper target even when visibleRequested
// is false.
- if (ar != null && !ar.isVisibleRequested() && !tc.inTransition(ar)) {
+ if (ar != null && !ar.isVisibleRequested() && !ar.isVisible()) {
// An activity that is not going to remain visible shouldn't be the target.
return false;
}
@@ -255,7 +254,7 @@ class WallpaperController {
resources.getBoolean(
com.android.internal.R.bool.config_offsetWallpaperToCenterOfLargestDisplay);
mIsLockscreenLiveWallpaperEnabled =
- SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", false);
+ SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true);
}
void resetLargestDisplay(Display display) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0152666a830d..4bc4c266c114 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -4141,7 +4141,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
getDisplayContent().getInsetsStateController().getSourceProviders();
for (int i = providers.size(); i >= 0; i--) {
final InsetsSourceProvider insetProvider = providers.valueAt(i);
- if (!insetProvider.getSource().insetsRoundedCornerFrame()) {
+ if (!insetProvider.getSource().hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
return;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 92d4cec80cc9..9e7df004806b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -370,6 +370,13 @@ public abstract class WindowManagerInternal {
public abstract void requestTraversalFromDisplayManager();
/**
+ * Called just before display manager has applied the device state to the displays
+ * @param deviceState device state as defined by
+ * {@link android.hardware.devicestate.DeviceStateManager}
+ */
+ public abstract void onDisplayManagerReceivedDeviceState(int deviceState);
+
+ /**
* Set by the accessibility layer to observe changes in the magnified region,
* rotation, and other window transformations related to display magnification
* as the window manager is responsible for doing the actual magnification
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9c636ea0ae85..7460d12d20b2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7675,6 +7675,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void onDisplayManagerReceivedDeviceState(int deviceState) {
+ mH.post(() -> {
+ synchronized (mGlobalLock) {
+ mRoot.onDisplayManagerReceivedDeviceState(deviceState);
+ }
+ });
+ }
+
+ @Override
public void setMagnificationSpec(int displayId, MagnificationSpec spec) {
synchronized (mGlobalLock) {
if (mAccessibilityController.hasCallbacks()) {
@@ -8261,6 +8270,13 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void addTrustedTaskOverlay(int taskId,
SurfaceControlViewHost.SurfacePackage overlay) {
+ if (overlay == null) {
+ throw new IllegalArgumentException("Invalid overlay passed in for task=" + taskId);
+ } else if (overlay.getSurfaceControl() == null
+ || !overlay.getSurfaceControl().isValid()) {
+ throw new IllegalArgumentException(
+ "Invalid overlay surfacecontrol passed in for task=" + taskId);
+ }
synchronized (mGlobalLock) {
final Task task = mRoot.getRootTask(taskId);
if (task == null) {
@@ -8273,6 +8289,13 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void removeTrustedTaskOverlay(int taskId,
SurfaceControlViewHost.SurfacePackage overlay) {
+ if (overlay == null) {
+ throw new IllegalArgumentException("Invalid overlay passed in for task=" + taskId);
+ } else if (overlay.getSurfaceControl() == null
+ || !overlay.getSurfaceControl().isValid()) {
+ throw new IllegalArgumentException(
+ "Invalid overlay surfacecontrol passed in for task=" + taskId);
+ }
synchronized (mGlobalLock) {
final Task task = mRoot.getRootTask(taskId);
if (task == null) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 7e34d15ddcfc..8e85e5bca240 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -960,20 +960,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
errorCallbackToken, organizer);
break;
}
- default: {
- // The other operations may change task order so they are skipped while in lock
- // task mode. The above operations are still allowed because they don't move
- // tasks. And it may be necessary such as clearing launch root after entering
- // lock task mode.
- if (isInLockTaskMode) {
- Slog.w(TAG, "Skip applying hierarchy operation " + hop
- + " while in lock task mode");
- return effects;
- }
- }
- }
-
- switch (type) {
case HIERARCHY_OP_TYPE_PENDING_INTENT: {
final Bundle launchOpts = hop.getLaunchOptions();
ActivityOptions activityOptions = launchOpts != null
@@ -1012,6 +998,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
break;
}
+ default: {
+ // The other operations may change task order so they are skipped while in lock
+ // task mode. The above operations are still allowed because they don't move
+ // tasks. And it may be necessary such as clearing launch root after entering
+ // lock task mode.
+ if (isInLockTaskMode) {
+ Slog.w(TAG, "Skip applying hierarchy operation " + hop
+ + " while in lock task mode");
+ return effects;
+ }
+ }
+ }
+
+ switch (type) {
case HIERARCHY_OP_TYPE_START_SHORTCUT: {
final Bundle launchOpts = hop.getLaunchOptions();
final String callingPackage = launchOpts.getString(
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 7cd7f6975bbd..8f49384f6101 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3883,13 +3883,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
/**
- * @return true if activity bounds are letterboxed or letterboxed for diplay cutout.
+ * @return {@code true} if activity bounds are letterboxed or letterboxed for display cutout.
+ * Note that it's always {@code false} if the activity is in pip mode.
*
* <p>Note that letterbox UI may not be shown even when this returns {@code true}. See {@link
* LetterboxUiController#shouldShowLetterboxUi} for more context.
*/
boolean areAppWindowBoundsLetterboxed() {
return mActivityRecord != null
+ && !mActivityRecord.inPinnedWindowingMode()
&& (mActivityRecord.areBoundsLetterboxed() || isLetterboxedForDisplayCutout());
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 2f1bf35a5ca8..8587270dd187 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -2214,13 +2214,25 @@ static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId
jCapability |= env->GetStaticIntField(gLightClassInfo.clazz,
gLightClassInfo.lightCapabilityColorRgb);
}
+
+ ScopedLocalRef<jintArray> jPreferredBrightnessLevels{env};
+ if (!lightInfo.preferredBrightnessLevels.empty()) {
+ std::vector<int32_t> vec;
+ for (auto it : lightInfo.preferredBrightnessLevels) {
+ vec.push_back(ftl::to_underlying(it));
+ }
+ jPreferredBrightnessLevels.reset(env->NewIntArray(vec.size()));
+ env->SetIntArrayRegion(jPreferredBrightnessLevels.get(), 0, vec.size(), vec.data());
+ }
+
ScopedLocalRef<jobject> lightObj(env,
env->NewObject(gLightClassInfo.clazz,
gLightClassInfo.constructor,
static_cast<jint>(lightInfo.id),
env->NewStringUTF(lightInfo.name.c_str()),
static_cast<jint>(lightInfo.ordinal),
- jTypeId, jCapability));
+ jTypeId, jCapability,
+ jPreferredBrightnessLevels.get()));
// Add light object to list
env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get());
}
@@ -2846,7 +2858,7 @@ int register_android_server_InputManager(JNIEnv* env) {
FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light");
gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>",
- "(ILjava/lang/String;III)V");
+ "(ILjava/lang/String;III[I)V");
gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
gLightClassInfo.lightTypeInput =
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 79c03497223a..5ba22830eec9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -454,8 +454,8 @@ final class DevicePolicyEngine {
onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
}
- applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
- policyDefinition, enforcingAdmin, /* value= */ null, /* enforcePolicy= */ true);
+ applyGlobalPolicyOnUsersWithLocalPoliciesLocked(policyDefinition, enforcingAdmin,
+ /* value= */ null, /* skipEnforcePolicy= */ false);
sendPolicyResultToAdmin(
enforcingAdmin,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2846b394e6e7..a5b15489f292 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -49,6 +49,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_TASK;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MICROPHONE;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MOBILE_NETWORK;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MODIFY_USERS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY;
@@ -73,7 +74,6 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_TIME;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER;
-import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USERS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_VPN;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WALLPAPER;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI;
@@ -139,6 +139,7 @@ import static android.app.admin.DevicePolicyManager.ID_TYPE_INDIVIDUAL_ATTESTATI
import static android.app.admin.DevicePolicyManager.ID_TYPE_MEID;
import static android.app.admin.DevicePolicyManager.ID_TYPE_SERIAL;
import static android.app.admin.DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD;
@@ -2191,7 +2192,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void suspendAppsForQuietProfiles(boolean toSuspend) {
PackageManagerInternal pmi = mInjector.getPackageManagerInternal();
- List<UserInfo> users = mUserManager.getUsers();
+ List<UserInfo> users = mUserManagerInternal.getUsers(true /* excludeDying */);
for (UserInfo user : users) {
if (user.isManagedProfile() && user.isQuietModeEnabled()) {
pmi.setPackagesSuspendedForQuietMode(user.id, toSuspend);
@@ -10117,6 +10118,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mOwners.clearDeviceOwner();
mOwners.writeDeviceOwner();
+ updateAdminCanGrantSensorsPermissionCache(userId);
clearDeviceOwnerUserRestriction(UserHandle.of(userId));
mInjector.securityLogSetLoggingEnabledProperty(false);
mSecurityLogMonitor.stop();
@@ -11112,7 +11114,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|| hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS);
}
- private boolean canUserUseLockTaskLocked(int userId) {
+ private boolean canDPCManagedUserUseLockTaskLocked(int userId) {
if (isUserAffiliatedWithDeviceLocked(userId)) {
return true;
}
@@ -11121,19 +11123,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (mOwners.hasDeviceOwner()) {
return false;
}
-
- if (!isPermissionCheckFlagEnabled() && !isPolicyEngineForFinanceFlagEnabled()) {
- final ComponentName profileOwner = getProfileOwnerAsUser(userId);
- if (profileOwner == null) {
- return false;
- }
+
+ final ComponentName profileOwner = getProfileOwnerAsUser(userId);
+ if (profileOwner == null) {
+ return false;
}
-
// Managed profiles are not allowed to use lock task
if (isManagedProfile(userId)) {
return false;
}
-
+
return true;
}
private void enforceCanQueryLockTaskLocked(ComponentName who, String callerPackageName) {
@@ -11141,7 +11140,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int userId = caller.getUserId();
enforceCanQuery(MANAGE_DEVICE_POLICY_LOCK_TASK, caller.getPackageName(), userId);
- if (!canUserUseLockTaskLocked(userId)) {
+ if ((isDeviceOwner(caller) || isProfileOwner(caller))
+ && !canDPCManagedUserUseLockTaskLocked(userId)) {
throw new SecurityException("User " + userId + " is not allowed to use lock task");
}
}
@@ -11157,7 +11157,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
caller.getPackageName(),
userId
);
- if (!canUserUseLockTaskLocked(userId)) {
+ if ((isDeviceOwner(caller) || isProfileOwner(caller))
+ && !canDPCManagedUserUseLockTaskLocked(userId)) {
throw new SecurityException("User " + userId + " is not allowed to use lock task");
}
return enforcingAdmin;
@@ -11168,7 +11169,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|| isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller));
final int userId = caller.getUserId();
- if (!canUserUseLockTaskLocked(userId)) {
+ if (!canDPCManagedUserUseLockTaskLocked(userId)) {
throw new SecurityException("User " + userId + " is not allowed to use lock task");
}
}
@@ -13720,7 +13721,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_ADD_CLONE_PROFILE, new String[]{MANAGE_DEVICE_POLICY_PROFILES});
USER_RESTRICTION_PERMISSIONS.put(
- UserManager.DISALLOW_ADD_USER, new String[]{MANAGE_DEVICE_POLICY_USERS});
+ UserManager.DISALLOW_ADD_USER, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_ADD_WIFI_CONFIG, new String[]{MANAGE_DEVICE_POLICY_WIFI});
USER_RESTRICTION_PERMISSIONS.put(
@@ -13810,13 +13811,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_PRINTING, new String[]{MANAGE_DEVICE_POLICY_PRINTING});
USER_RESTRICTION_PERMISSIONS.put(
- UserManager.DISALLOW_REMOVE_USER, new String[]{MANAGE_DEVICE_POLICY_USERS});
+ UserManager.DISALLOW_REMOVE_USER, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_RUN_IN_BACKGROUND, new String[]{MANAGE_DEVICE_POLICY_RUN_IN_BACKGROUND});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_SAFE_BOOT, new String[]{MANAGE_DEVICE_POLICY_SAFE_BOOT});
USER_RESTRICTION_PERMISSIONS.put(
- UserManager.DISALLOW_SET_USER_ICON, new String[]{MANAGE_DEVICE_POLICY_USERS});
+ UserManager.DISALLOW_SET_USER_ICON, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_SET_WALLPAPER, new String[]{MANAGE_DEVICE_POLICY_WALLPAPER});
USER_RESTRICTION_PERMISSIONS.put(
@@ -13842,7 +13843,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_USB_FILE_TRANSFER, new String[]{MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER});
USER_RESTRICTION_PERMISSIONS.put(
- UserManager.DISALLOW_USER_SWITCH, new String[]{MANAGE_DEVICE_POLICY_USERS});
+ UserManager.DISALLOW_USER_SWITCH, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_WIFI_DIRECT, new String[]{MANAGE_DEVICE_POLICY_WIFI});
USER_RESTRICTION_PERMISSIONS.put(
@@ -14906,8 +14907,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy = new LockTaskPolicy(currentPolicy);
policy.setPackages(Set.of(packages));
}
- if (policy.getPackages().isEmpty()
- && policy.getFlags() == DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
+ if (policy.getPackages().isEmpty()) {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.LOCK_TASK,
enforcingAdmin,
@@ -15100,7 +15100,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final List<UserInfo> userInfos = mUserManager.getAliveUsers();
for (int i = userInfos.size() - 1; i >= 0; i--) {
int userId = userInfos.get(i).id;
- if (canUserUseLockTaskLocked(userId)) {
+ if (canDPCManagedUserUseLockTaskLocked(userId)) {
continue;
}
@@ -15140,7 +15140,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void enforceCanSetLockTaskFeaturesOnFinancedDevice(CallerIdentity caller, int flags) {
int allowedFlags = LOCK_TASK_FEATURE_SYSTEM_INFO | LOCK_TASK_FEATURE_KEYGUARD
| LOCK_TASK_FEATURE_HOME | LOCK_TASK_FEATURE_GLOBAL_ACTIONS
- | LOCK_TASK_FEATURE_NOTIFICATIONS;
+ | LOCK_TASK_FEATURE_NOTIFICATIONS | LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK;
if (!isFinancedDeviceOwner(caller)) {
return;
@@ -15151,7 +15151,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
"Permitted lock task features when managing a financed device: "
+ "LOCK_TASK_FEATURE_SYSTEM_INFO, LOCK_TASK_FEATURE_KEYGUARD, "
+ "LOCK_TASK_FEATURE_HOME, LOCK_TASK_FEATURE_GLOBAL_ACTIONS, "
- + "or LOCK_TASK_FEATURE_NOTIFICATIONS");
+ + "LOCK_TASK_FEATURE_NOTIFICATIONS"
+ + " or LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK");
}
}
@@ -20689,7 +20690,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void addUserControlDisabledPackages(CallerIdentity caller,
EnforcingAdmin enforcingAdmin, Set<String> packages) {
- if (isCallerDeviceOwner(caller)) {
+ if (isDeviceOwner(caller)) {
mDevicePolicyEngine.setGlobalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin,
@@ -20705,7 +20706,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void removeUserControlDisabledPackages(CallerIdentity caller,
EnforcingAdmin enforcingAdmin) {
- if (isCallerDeviceOwner(caller)) {
+ if (isDeviceOwner(caller)) {
mDevicePolicyEngine.removeGlobalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin);
@@ -20717,12 +20718,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- private boolean isCallerDeviceOwner(CallerIdentity caller) {
- synchronized (getLockObject()) {
- return getDeviceOwnerUserIdUncheckedLocked() == caller.getUserId();
- }
- }
-
@Override
public List<String> getUserControlDisabledPackages(ComponentName who,
String callerPackageName) {
@@ -23026,6 +23021,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_LOCK_TASK,
MANAGE_DEVICE_POLICY_MICROPHONE,
MANAGE_DEVICE_POLICY_MOBILE_NETWORK,
+ MANAGE_DEVICE_POLICY_MODIFY_USERS,
MANAGE_DEVICE_POLICY_MTE,
MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION,
MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
@@ -23049,7 +23045,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_TIME,
MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING,
MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER,
- MANAGE_DEVICE_POLICY_USERS,
MANAGE_DEVICE_POLICY_VPN,
MANAGE_DEVICE_POLICY_WALLPAPER,
MANAGE_DEVICE_POLICY_WIFI,
@@ -23070,12 +23065,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_KEYGUARD,
MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
MANAGE_DEVICE_POLICY_LOCK_TASK,
+ MANAGE_DEVICE_POLICY_MODIFY_USERS,
MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
MANAGE_DEVICE_POLICY_SAFE_BOOT,
MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE,
MANAGE_DEVICE_POLICY_TIME,
- MANAGE_DEVICE_POLICY_USERS,
MANAGE_DEVICE_POLICY_WIPE_DATA
);
@@ -23161,6 +23156,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_FUN,
MANAGE_DEVICE_POLICY_LOCK_TASK,
MANAGE_DEVICE_POLICY_MOBILE_NETWORK,
+ MANAGE_DEVICE_POLICY_MODIFY_USERS,
MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA,
MANAGE_DEVICE_POLICY_PRINTING,
MANAGE_DEVICE_POLICY_PROFILES,
@@ -23169,7 +23165,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_SMS,
MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS,
MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER,
- MANAGE_DEVICE_POLICY_USERS,
MANAGE_DEVICE_POLICY_WINDOWS,
SET_TIME,
SET_TIME_ZONE
@@ -23359,6 +23354,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_TASK,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_MODIFY_USERS,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
@@ -23379,8 +23376,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
- CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_USERS,
- MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_VPN,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_WALLPAPER,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 0c1c406dd7e2..bb275e45b55a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -204,7 +204,15 @@ class Owners {
@GuardedBy("mData")
Set<Integer> getProfileOwnerUidsLocked() {
- return mData.mProfileOwners.keySet();
+ Set<Integer> uids = new ArraySet<>();
+ for (int i = 0; i < mData.mProfileOwners.size(); i++) {
+ int userId = mData.mProfileOwners.keyAt(i);
+ OwnerInfo info = mData.mProfileOwners.valueAt(i);
+ uids.add(mPackageManagerInternal.getPackageUid(info.packageName,
+ PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
+ userId));
+ }
+ return uids;
}
String getDeviceOwnerPackageName() {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 454337fcf141..3b048b250075 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -167,7 +167,7 @@ final class PolicyEnforcerCallbacks {
packages == null ? null : packages.stream().toList());
LocalServices.getService(UsageStatsManagerInternal.class)
.setAdminProtectedPackages(
- packages == null ? null : new ArraySet(packages), userId);
+ packages == null ? null : new ArraySet<>(packages), userId);
});
return true;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index af841808992e..991248aceb4b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -3255,6 +3255,12 @@ public final class SystemServer implements Dumpable {
Slog.d(TAG, "ContentCaptureService disabled because resource is not overlaid");
return;
}
+ if (!deviceHasConfigString(context, R.string.config_defaultContentProtectionService)) {
+ Slog.d(
+ TAG,
+ "ContentProtectionService disabled because resource is not overlaid,"
+ + " ContentCaptureService still enabled");
+ }
}
t.traceBegin("StartContentCaptureService");
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index f47954baf649..948687ae1645 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -77,6 +77,7 @@ import android.os.Bundle;
import android.os.BundleMerger;
import android.os.DropBoxManager;
import android.os.HandlerThread;
+import android.os.Process;
import android.os.SystemClock;
import android.os.TestLooperManager;
import android.os.UserHandle;
@@ -327,6 +328,20 @@ public final class BroadcastQueueModernImplTest {
}
@Test
+ public void testRunnableList_sameRunnableAt() {
+ doReturn(2L).when(mQueue1).getRunnableAt();
+ doReturn(2L).when(mQueue2).getRunnableAt();
+ doReturn(2L).when(mQueue3).getRunnableAt();
+ doReturn(2L).when(mQueue4).getRunnableAt();
+
+ mHead = insertIntoRunnableList(mHead, mQueue1);
+ mHead = insertIntoRunnableList(mHead, mQueue2);
+ mHead = insertIntoRunnableList(mHead, mQueue3);
+ mHead = insertIntoRunnableList(mHead, mQueue4);
+ assertRunnableList(List.of(mQueue1, mQueue2, mQueue3, mQueue4), mHead);
+ }
+
+ @Test
public void testProcessQueue_Complex() {
BroadcastProcessQueue red = mImpl.getOrCreateProcessQueue(PACKAGE_RED, TEST_UID);
BroadcastProcessQueue green = mImpl.getOrCreateProcessQueue(PACKAGE_GREEN, TEST_UID);
@@ -561,6 +576,20 @@ public final class BroadcastQueueModernImplTest {
assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
}
+ @Test
+ public void testRunnableAt_coreUid() {
+ final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+ "com.android.bluetooth", Process.BLUETOOTH_UID);
+
+ final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+ final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
+ List.of(makeMockRegisteredReceiver()));
+ enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
+
+ assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime);
+ assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
+ }
+
/**
* Verify that a cached process that would normally be delayed becomes
* immediately runnable when the given broadcast is enqueued.
@@ -947,6 +976,166 @@ public final class BroadcastQueueModernImplTest {
List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
}
+ @Test
+ public void testDeliveryGroupPolicy_diffReceivers() {
+ final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+ final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+ final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+ .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+ .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+ final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+ final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+ final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), false));
+ final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+ final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+ getUidForPackage(PACKAGE_RED));
+ final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+ getUidForPackage(PACKAGE_BLUE));
+ verifyPendingRecords(greenQueue, List.of(screenOff));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff));
+
+ assertTrue(greenQueue.isEmpty());
+ assertTrue(redQueue.isEmpty());
+ assertTrue(blueQueue.isEmpty());
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), false));
+ verifyPendingRecords(greenQueue, List.of(screenOn));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOn));
+ }
+
+ @Test
+ public void testDeliveryGroupPolicy_ordered_diffReceivers() {
+ final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+ final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+ final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+ .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+ .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+ final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+ final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+ final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), true));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), true));
+ final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+ final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+ getUidForPackage(PACKAGE_RED));
+ final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+ getUidForPackage(PACKAGE_BLUE));
+ verifyPendingRecords(greenQueue, List.of(screenOff));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff));
+
+ assertTrue(greenQueue.isEmpty());
+ assertTrue(redQueue.isEmpty());
+ assertTrue(blueQueue.isEmpty());
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), true));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), true));
+ verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+ }
+
+ @Test
+ public void testDeliveryGroupPolicy_resultTo_diffReceivers() {
+ final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+ final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+ final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+ .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+ .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+ final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+ final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+ final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+ final IIntentReceiver resultTo = mock(IIntentReceiver.class);
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), resultTo, false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
+ final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+ final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+ getUidForPackage(PACKAGE_RED));
+ final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+ getUidForPackage(PACKAGE_BLUE));
+ verifyPendingRecords(greenQueue, List.of(screenOff));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff));
+
+ assertTrue(greenQueue.isEmpty());
+ assertTrue(redQueue.isEmpty());
+ assertTrue(blueQueue.isEmpty());
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), resultTo, false));
+ verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+ }
+
+ @Test
+ public void testDeliveryGroupPolicy_prioritized_diffReceivers() {
+ final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+ final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+ final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+ .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+ .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+ final Object greenReceiver = withPriority(
+ makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
+ final Object redReceiver = withPriority(
+ makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
+ final Object blueReceiver = withPriority(
+ makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), false));
+ final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+ final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+ getUidForPackage(PACKAGE_RED));
+ final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+ getUidForPackage(PACKAGE_BLUE));
+ verifyPendingRecords(greenQueue, List.of(screenOff));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff));
+
+ assertTrue(greenQueue.isEmpty());
+ assertTrue(redQueue.isEmpty());
+ assertTrue(blueQueue.isEmpty());
+
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+ List.of(greenReceiver, redReceiver, blueReceiver), false));
+ mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+ List.of(greenReceiver, blueReceiver), false));
+ verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+ verifyPendingRecords(redQueue, List.of(screenOff));
+ verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+ }
+
/**
* Verify that sending a broadcast with DELIVERY_GROUP_POLICY_MERGED works as expected.
*/
@@ -1217,7 +1406,8 @@ public final class BroadcastQueueModernImplTest {
eq(getUidForPackage(PACKAGE_GREEN)), anyInt(), eq(Intent.ACTION_TIME_TICK),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD),
- anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class), anyString()),
+ anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class),
+ anyString(), anyInt(), anyInt()),
times(1));
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 636576492362..4989f841a275 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -276,7 +276,11 @@ public class BroadcastQueueTest {
switch (behavior) {
case SUCCESS:
case SUCCESS_PREDECESSOR:
- mQueue.onApplicationAttachedLocked(deliverRes);
+ try {
+ mQueue.onApplicationAttachedLocked(deliverRes);
+ } catch (BroadcastDeliveryFailedException e) {
+ Log.v(TAG, "Error while invoking onApplicationAttachedLocked", e);
+ }
break;
case FAIL_TIMEOUT:
case FAIL_TIMEOUT_PREDECESSOR:
@@ -1120,6 +1124,7 @@ public class BroadcastQueueTest {
final ProcessRecord restartedReceiverApp = mAms.getProcessRecordLocked(PACKAGE_GREEN,
getUidForPackage(PACKAGE_GREEN));
assertNotEquals(receiverApp, restartedReceiverApp);
+ verifyScheduleReceiver(restartedReceiverApp, airplane);
verifyScheduleReceiver(restartedReceiverApp, timezone);
}
@@ -1304,12 +1309,7 @@ public class BroadcastQueueTest {
final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
getUidForPackage(PACKAGE_ORANGE));
- if (mImpl == Impl.MODERN) {
- // Modern queue does not retry sending a broadcast once any broadcast delivery fails.
- assertNull(receiverGreenApp);
- } else {
- verifyScheduleReceiver(times(1), receiverGreenApp, airplane);
- }
+ verifyScheduleReceiver(times(1), receiverGreenApp, airplane);
verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
verifyScheduleReceiver(times(1), receiverYellowApp, airplane);
verifyScheduleReceiver(times(1), receiverOrangeApp, timezone);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index cda5456723fb..770f04a2db5e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -68,6 +68,7 @@ import static com.android.server.am.ProcessList.UNKNOWN_ADJ;
import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalAnswers.answer;
@@ -2489,6 +2490,28 @@ public class MockingOomAdjusterTests {
assertProcStates(app2, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testUpdateOomAdj_DoOne_AboveClient_SameProcess() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState();
+ doReturn(app).when(sService).getTopApp();
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OOM_ADJ_REASON_NONE);
+
+ assertEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+
+ // Simulate binding to a service in the same process using BIND_ABOVE_CLIENT and
+ // verify that its OOM adjustment level is unaffected.
+ bindService(app, app, null, Context.BIND_ABOVE_CLIENT, mock(IBinder.class));
+ app.mServices.updateHasAboveClientLocked();
+ assertFalse(app.mServices.hasAboveClient());
+
+ sService.mOomAdjuster.updateOomAdjLocked(app, OOM_ADJ_REASON_NONE);
+ assertEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ }
+
private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
String packageName, boolean hasShownUi) {
long now = SystemClock.uptimeMillis();
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 8dc0ac6515cd..efd82fa1136d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -813,7 +813,7 @@ public final class DisplayPowerController2Test {
any(HysteresisLevels.class),
any(HysteresisLevels.class),
eq(mContext),
- any(HighBrightnessModeController.class),
+ any(BrightnessRangeController.class),
any(BrightnessThrottler.class),
isNull(),
anyInt(),
@@ -1062,7 +1062,7 @@ public final class DisplayPowerController2Test {
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController,
+ BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper,
int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 5c0810fdca44..a93640b592cd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -819,7 +819,7 @@ public final class DisplayPowerControllerTest {
any(HysteresisLevels.class),
any(HysteresisLevels.class),
eq(mContext),
- any(HighBrightnessModeController.class),
+ any(BrightnessRangeController.class),
any(BrightnessThrottler.class),
isNull(),
anyInt(),
@@ -1038,7 +1038,7 @@ public final class DisplayPowerControllerTest {
HysteresisLevels screenBrightnessThresholds,
HysteresisLevels ambientBrightnessThresholdsIdle,
HysteresisLevels screenBrightnessThresholdsIdle, Context context,
- HighBrightnessModeController hbmController,
+ BrightnessRangeController brightnessRangeController,
BrightnessThrottler brightnessThrottler,
BrightnessMappingStrategy idleModeBrightnessMapper,
int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 5f82ec1dde02..f89f73c98cfd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -36,6 +37,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Rect;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -981,6 +983,7 @@ public class LocalDisplayAdapterTest {
DisplayDevice displayDevice = mListener.addedDisplays.get(0);
// Turn on / initialize
+ assumeTrue(displayDevice.getDisplayDeviceConfig().hasSdrToHdrRatioSpline());
Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_ON, 0,
0);
changeStateRunnable.run();
@@ -1007,6 +1010,72 @@ public class LocalDisplayAdapterTest {
0.001f);
}
+ @Test
+ public void test_getDisplayDeviceInfoLocked_internalDisplay_usesCutoutAndCorners()
+ throws Exception {
+ setupCutoutAndRoundedCorners();
+ FakeDisplay display = new FakeDisplay(PORT_A);
+ display.info.isInternal = true;
+ setUpDisplay(display);
+ updateAvailableDisplays();
+ mAdapter.registerLocked();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+ assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+ DisplayDevice displayDevice = mListener.addedDisplays.get(0);
+
+ // Turn on / initialize
+ Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_ON, 0,
+ 0);
+ changeStateRunnable.run();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+ mListener.changedDisplays.clear();
+
+ DisplayDeviceInfo info = displayDevice.getDisplayDeviceInfoLocked();
+
+ assertThat(info.displayCutout).isNotNull();
+ assertThat(info.displayCutout.getBoundingRectTop()).isEqualTo(new Rect(507, 33, 573, 99));
+ assertThat(info.roundedCorners).isNotNull();
+ assertThat(info.roundedCorners.getRoundedCorner(0).getRadius()).isEqualTo(5);
+ }
+
+ @Test public void test_getDisplayDeviceInfoLocked_externalDisplay_doesNotUseCutoutOrCorners()
+ throws Exception {
+ setupCutoutAndRoundedCorners();
+ FakeDisplay display = new FakeDisplay(PORT_A);
+ display.info.isInternal = false;
+ setUpDisplay(display);
+ updateAvailableDisplays();
+ mAdapter.registerLocked();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+ assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+ DisplayDevice displayDevice = mListener.addedDisplays.get(0);
+
+ // Turn on / initialize
+ Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_ON, 0,
+ 0);
+ changeStateRunnable.run();
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+ mListener.changedDisplays.clear();
+
+ DisplayDeviceInfo info = displayDevice.getDisplayDeviceInfoLocked();
+
+ assertThat(info.displayCutout).isNull();
+ assertThat(info.roundedCorners).isNull();
+ }
+
+ private void setupCutoutAndRoundedCorners() {
+ String sampleCutout = "M 507,66\n"
+ + "a 33,33 0 1 0 66,0 33,33 0 1 0 -66,0\n"
+ + "Z\n"
+ + "@left\n";
+ // Setup some default cutout
+ when(mMockedResources.getString(
+ com.android.internal.R.string.config_mainBuiltInDisplayCutout))
+ .thenReturn(sampleCutout);
+ when(mMockedResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.rounded_corner_radius)).thenReturn(5);
+ }
+
private void assertDisplayDpi(DisplayDeviceInfo info, int expectedPort,
float expectedXdpi,
float expectedYDpi,
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 8cfc150afe56..7e638a869682 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -280,6 +280,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testRegisterProxy() throws Exception {
+ when(mProxyManager.displayBelongsToCaller(anyInt(), anyInt())).thenReturn(true);
mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY), anyInt(),
eq(mMockSecurityPolicy),
@@ -289,9 +290,9 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
- public void testRegisterProxyWithoutA11yPermission() throws Exception {
+ public void testRegisterProxyWithoutA11yPermissionOrRole() throws Exception {
doThrow(SecurityException.class).when(mMockSecurityPolicy)
- .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
+ .checkForAccessibilityPermissionOrRole();
assertThrows(SecurityException.class,
() -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
@@ -314,7 +315,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testRegisterProxyForDefaultDisplay() throws Exception {
- assertThrows(IllegalArgumentException.class,
+ assertThrows(SecurityException.class,
() -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY));
verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
any(), any(), any());
@@ -332,6 +333,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testUnRegisterProxyWithPermission() throws Exception {
+ when(mProxyManager.displayBelongsToCaller(anyInt(), anyInt())).thenReturn(true);
mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
mA11yms.unregisterProxyForDisplay(TEST_DISPLAY);
@@ -340,9 +342,9 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
- public void testUnRegisterProxyWithoutA11yPermission() {
+ public void testUnRegisterProxyWithoutA11yPermissionOrRole() {
doThrow(SecurityException.class).when(mMockSecurityPolicy)
- .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
+ .checkForAccessibilityPermissionOrRole();
assertThrows(SecurityException.class,
() -> mA11yms.unregisterProxyForDisplay(TEST_DISPLAY));
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index b0fd64976c48..c98de7c4d00e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -66,6 +66,7 @@ import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -307,6 +308,7 @@ public class WindowMagnificationManagerTest {
MagnificationScaleProvider.MAX_SCALE);
}
+ @Ignore("b/278816260: We could refer to b/182561174#comment4 for solution.")
@Test
public void logTrackingTypingFocus_processScroll_logDuration() {
WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager);
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 317fd58e0c76..dccacb4d301a 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -58,6 +58,7 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -103,11 +104,13 @@ import com.android.server.am.UserState.KeyEvictedCallback;
import com.android.server.pm.UserJourneyLogger;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
+import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
import java.util.Arrays;
@@ -187,6 +190,7 @@ public class UserControllerTest {
doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
+ doNothing().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();
mockIsUsersOnSecondaryDisplaysEnabled(false);
// All UserController params are set to default.
@@ -951,6 +955,45 @@ public class UserControllerTest {
.systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
}
+ @Test
+ public void testStallUserSwitchUntilTheKeyguardIsShown() throws Exception {
+ // enable user switch ui, because keyguard is only shown then
+ mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
+ /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
+
+ // mock the device to be secure in order to expect the keyguard to be shown
+ when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
+
+ // call real lockDeviceNowAndWaitForKeyguardShown method for this test
+ doCallRealMethod().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();
+
+ // call startUser on a thread because we're expecting it to be blocked
+ Thread threadStartUser = new Thread(()-> {
+ mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
+ });
+ threadStartUser.start();
+
+ // make sure the switch is stalled...
+ Thread.sleep(2000);
+ // by checking REPORT_USER_SWITCH_MSG is not sent yet
+ assertNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
+ // and the thread is still alive
+ assertTrue(threadStartUser.isAlive());
+
+ // mock send the keyguard shown event
+ ArgumentCaptor<ActivityTaskManagerInternal.ScreenObserver> captor = ArgumentCaptor.forClass(
+ ActivityTaskManagerInternal.ScreenObserver.class);
+ verify(mInjector.mActivityTaskManagerInternal).registerScreenObserver(captor.capture());
+ captor.getValue().onKeyguardStateChanged(true);
+
+ // verify the switch now moves on...
+ Thread.sleep(1000);
+ // by checking REPORT_USER_SWITCH_MSG is sent
+ assertNotNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
+ // and the thread is finished
+ assertFalse(threadStartUser.isAlive());
+ }
+
private void setUpAndStartUserInBackground(int userId) throws Exception {
setUpUser(userId, 0);
mUserController.startUser(userId, USER_START_MODE_BACKGROUND);
@@ -1092,6 +1135,7 @@ public class UserControllerTest {
private final IStorageManager mStorageManagerMock;
private final UserManagerInternal mUserManagerInternalMock;
private final WindowManagerService mWindowManagerMock;
+ private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
private final KeyguardManager mKeyguardManagerMock;
private final LockPatternUtils mLockPatternUtilsMock;
@@ -1111,6 +1155,7 @@ public class UserControllerTest {
mUserManagerMock = mock(UserManagerService.class);
mUserManagerInternalMock = mock(UserManagerInternal.class);
mWindowManagerMock = mock(WindowManagerService.class);
+ mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
mStorageManagerMock = mock(IStorageManager.class);
mKeyguardManagerMock = mock(KeyguardManager.class);
when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
@@ -1172,6 +1217,11 @@ public class UserControllerTest {
}
@Override
+ ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+ return mActivityTaskManagerInternal;
+ }
+
+ @Override
KeyguardManager getKeyguardManager() {
return mKeyguardManagerMock;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 4268eb924225..662477ddbbe9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -18,6 +18,9 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON;
+import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED;
+import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED;
import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_NEGATIVE;
import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
@@ -32,6 +35,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -45,6 +49,7 @@ import android.app.trust.ITrustManager;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -64,7 +69,10 @@ import android.security.KeyStore;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricFrameworkStatsLogger;
+import com.android.server.biometrics.log.OperationContextExt;
import org.junit.Before;
import org.junit.Test;
@@ -95,6 +103,7 @@ public class AuthSessionTest {
@Mock private IBiometricSysuiReceiver mSysuiReceiver;
@Mock private KeyStore mKeyStore;
@Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver;
+ @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
private Random mRandom;
private IBinder mToken;
@@ -395,6 +404,84 @@ public class AuthSessionTest {
eq(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR_BASE), eq(acquiredStrVendor));
}
+ @Test
+ public void testLogOnDialogDismissed_authenticatedWithConfirmation() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_BIOMETRIC_CONFIRMED, null);
+ verify(mBiometricFrameworkStatsLogger, times(1)).authenticate(
+ (OperationContextExt) anyObject(),
+ eq(BiometricsProtoEnums.MODALITY_FACE),
+ eq(BiometricsProtoEnums.ACTION_UNKNOWN),
+ eq(BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT),
+ eq(false), /* debugEnabled */
+ anyLong(), /* latency */
+ eq(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED),
+ eq(true), /* confirmationRequired */
+ eq(0) /* userId */,
+ eq(-1f) /* ambientLightLux */);
+ }
+
+ @Test
+ public void testLogOnDialogDismissed_authenticatedWithoutConfirmation() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED, null);
+ verify(mBiometricFrameworkStatsLogger, never()).authenticate(
+ anyObject(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyLong(), anyInt(),
+ anyBoolean(), anyInt(), eq(-1f));
+ verify(mBiometricFrameworkStatsLogger, never()).error(
+ anyObject(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyLong(), anyInt(),
+ anyInt(), anyInt());
+ }
+
+ @Test
+ public void testLogOnDialogDismissed_error() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_NEGATIVE, null);
+ verify(mBiometricFrameworkStatsLogger, times(1)).error(
+ (OperationContextExt) anyObject(),
+ eq(BiometricsProtoEnums.MODALITY_FACE),
+ eq(BiometricsProtoEnums.ACTION_AUTHENTICATE),
+ eq(BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT),
+ eq(false),
+ anyLong(),
+ eq(BIOMETRIC_ERROR_NEGATIVE_BUTTON),
+ eq(0) /* vendorCode */,
+ eq(0) /* userId */);
+ }
+
// TODO (b/208484275) : Enable these tests
// @Test
// public void testPreAuth_canAuthAndPrivacyDisabled() throws Exception {
@@ -498,7 +585,7 @@ public class AuthSessionTest {
return new AuthSession(mContext, mBiometricContext, mStatusBarService, mSysuiReceiver,
mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId,
operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
- false /* debugEnabled */, mFingerprintSensorProps);
+ false /* debugEnabled */, mFingerprintSensorProps, mBiometricFrameworkStatsLogger);
}
private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
index fb3a5f64d808..a4423038a072 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
@@ -316,13 +316,13 @@ public class BiometricContextProviderTest {
assertThat(aidlContext.isAod).isEqualTo(false);
assertThat(aidlContext.isCrypto).isEqualTo(false);
- context = mProvider.updateContext(mOpContext, false /* crypto */);
+ context = mProvider.updateContext(mOpContext, true /* crypto */);
aidlContext = context.toAidlContext();
assertThat(context).isSameInstanceAs(mOpContext);
assertThat(aidlContext.id).isEqualTo(0);
assertThat(aidlContext.reason).isEqualTo(OperationReason.UNKNOWN);
assertThat(aidlContext.isAod).isEqualTo(false);
- assertThat(aidlContext.isCrypto).isEqualTo(false);
+ assertThat(aidlContext.isCrypto).isEqualTo(true);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
index 5cf59602a43b..32284fd7541a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
@@ -98,7 +98,7 @@ public class OperationContextExtTest {
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
final OperationContextExt context = new OperationContextExt(newAidlContext(), true);
when(mBiometricContext.getDisplayState()).thenReturn(entry.getKey());
- assertThat(context.update(mBiometricContext).getDisplayState())
+ assertThat(context.update(mBiometricContext, context.isCrypto()).getDisplayState())
.isEqualTo(entry.getValue());
}
}
@@ -139,7 +139,7 @@ public class OperationContextExtTest {
final OperationContextExt context = new OperationContextExt(newAidlContext(),
sessionType == OperationReason.BIOMETRIC_PROMPT);
- assertThat(context.update(mBiometricContext)).isSameInstanceAs(context);
+ assertThat(context.update(mBiometricContext, context.isCrypto())).isSameInstanceAs(context);
if (sessionInfo != null) {
assertThat(context.getId()).isEqualTo(sessionInfo.getId());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index d5d06d3b4eb8..046b01c831b5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -16,8 +16,10 @@
package com.android.server.biometrics.sensors.face.aidl;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -205,7 +207,9 @@ public class FaceAuthenticationClientTest {
client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
true /* authenticated */, new ArrayList<>());
- verify(mCancellationSignal).cancel();
+ verify(mCancellationSignal, never()).cancel();
+ verify(mClientMonitorCallbackConverter)
+ .onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
private FaceAuthenticationClient createClient() throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
index 25bd9bcf8d5c..be9f52e00b16 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
@@ -17,12 +17,14 @@
package com.android.server.biometrics.sensors.face.aidl;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,6 +43,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
@@ -82,6 +85,10 @@ public class SensorTest {
private AuthSessionCoordinator mAuthSessionCoordinator;
@Mock
FaceProvider mFaceProvider;
+ @Mock
+ BaseClientMonitor mClientMonitor;
+ @Mock
+ AidlSession mCurrentSession;
private final TestLooper mLooper = new TestLooper();
private final LockoutCache mLockoutCache = new LockoutCache();
@@ -161,6 +168,39 @@ public class SensorTest {
assertNull(sensor.getSessionForUser(USER_ID));
}
+ @Test
+ public void onBinderDied_cancelNonInterruptableClient() {
+ mLooper.dispatchAll();
+
+ when(mCurrentSession.getUserId()).thenReturn(USER_ID);
+ when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
+ when(mClientMonitor.isInterruptable()).thenReturn(false);
+
+ final SensorProps sensorProps = new SensorProps();
+ sensorProps.commonProps = new CommonProps();
+ sensorProps.commonProps.sensorId = 1;
+ final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
+ sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
+ sensorProps.commonProps.maxEnrollmentsPerUser, null,
+ sensorProps.sensorType, sensorProps.supportsDetectInteraction,
+ sensorProps.halControlsPreview, false /* resetLockoutRequiresChallenge */);
+ final Sensor sensor = new Sensor("SensorTest", mFaceProvider, mContext, null,
+ internalProp, mLockoutResetDispatcher, mBiometricContext, mCurrentSession);
+ mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
+ sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
+ USER_ID, mHalCallback);
+
+ mScheduler.scheduleClientMonitor(mClientMonitor);
+
+ assertNotNull(mScheduler.getCurrentClient());
+
+ sensor.onBinderDied();
+
+ verify(mClientMonitor).cancel();
+ assertNull(sensor.getSessionForUser(USER_ID));
+ assertNull(mScheduler.getCurrentClient());
+ }
+
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index f8f40fe44457..c383a96d5de3 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -16,6 +16,8 @@
package com.android.server.biometrics.sensors.fingerprint.aidl;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -399,7 +401,9 @@ public class FingerprintAuthenticationClientTest {
mLooper.moveTimeForward(10);
mLooper.dispatchAll();
- verify(mCancellationSignal).cancel();
+ verify(mCancellationSignal, never()).cancel();
+ verify(mClientMonitorCallbackConverter)
+ .onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
private FingerprintAuthenticationClient createClient() throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
index 0c1346696b58..15d7601dde34 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
@@ -17,17 +17,23 @@
package com.android.server.biometrics.sensors.fingerprint.aidl;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.face.SensorProps;
import android.hardware.biometrics.fingerprint.ISession;
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Handler;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
@@ -37,11 +43,13 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
+import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import org.junit.Before;
import org.junit.Test;
@@ -76,6 +84,14 @@ public class SensorTest {
private BiometricContext mBiometricContext;
@Mock
private AuthSessionCoordinator mAuthSessionCoordinator;
+ @Mock
+ FingerprintProvider mFingerprintProvider;
+ @Mock
+ GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
+ @Mock
+ private AidlSession mCurrentSession;
+ @Mock
+ private BaseClientMonitor mClientMonitor;
private final TestLooper mLooper = new TestLooper();
private final LockoutCache mLockoutCache = new LockoutCache();
@@ -130,6 +146,40 @@ public class SensorTest {
verifyNotLocked();
}
+ @Test
+ public void onBinderDied_cancelNonInterruptableClient() {
+ mLooper.dispatchAll();
+
+ when(mCurrentSession.getUserId()).thenReturn(USER_ID);
+ when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
+ when(mClientMonitor.isInterruptable()).thenReturn(false);
+
+ final SensorProps sensorProps = new SensorProps();
+ sensorProps.commonProps = new CommonProps();
+ sensorProps.commonProps.sensorId = 1;
+ final FingerprintSensorPropertiesInternal internalProp = new
+ FingerprintSensorPropertiesInternal(
+ sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
+ sensorProps.commonProps.maxEnrollmentsPerUser, null,
+ sensorProps.sensorType, false /* resetLockoutRequiresHardwareAuthToken */);
+ final Sensor sensor = new Sensor("SensorTest", mFingerprintProvider, mContext,
+ null /* handler */, internalProp, mLockoutResetDispatcher,
+ mGestureAvailabilityDispatcher, mBiometricContext, mCurrentSession);
+ mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
+ sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
+ USER_ID, mHalCallback);
+
+ mScheduler.scheduleClientMonitor(mClientMonitor);
+
+ assertNotNull(mScheduler.getCurrentClient());
+
+ sensor.onBinderDied();
+
+ verify(mClientMonitor).cancel();
+ assertNull(sensor.getSessionForUser(USER_ID));
+ assertNull(mScheduler.getCurrentClient());
+ }
+
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
index 8a107ada16b0..dccc26af8024 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
@@ -18,7 +18,7 @@ package com.android.server.companion.datatransfer.contextsync;
import static com.google.common.truth.Truth.assertThat;
-import android.os.Parcel;
+import android.os.Bundle;
import android.testing.AndroidTestingRunner;
import org.junit.Test;
@@ -28,7 +28,7 @@ import org.junit.runner.RunWith;
public class CallMetadataSyncDataTest {
@Test
- public void call_writeToParcel_fromParcel_reconstructsSuccessfully() {
+ public void call_writeToBundle_fromBundle_reconstructsSuccessfully() {
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
final String id = "5";
final String callerId = "callerId";
@@ -36,6 +36,7 @@ public class CallMetadataSyncDataTest {
final String appName = "appName";
final String appIdentifier = "com.google.test";
final int status = 1;
+ final int direction = android.companion.Telecom.Call.OUTGOING;
final int control1 = 2;
final int control2 = 3;
call.setId(id);
@@ -45,14 +46,13 @@ public class CallMetadataSyncDataTest {
new CallMetadataSyncData.CallFacilitator(appName, appIdentifier);
call.setFacilitator(callFacilitator);
call.setStatus(status);
+ call.setDirection(direction);
call.addControl(control1);
call.addControl(control2);
- Parcel parcel = Parcel.obtain();
- call.writeToParcel(parcel, /* flags= */ 0);
- parcel.setDataPosition(0);
- final CallMetadataSyncData.Call reconstructedCall = CallMetadataSyncData.Call.fromParcel(
- parcel);
+ final Bundle bundle = call.writeToBundle();
+ final CallMetadataSyncData.Call reconstructedCall = CallMetadataSyncData.Call.fromBundle(
+ bundle);
assertThat(reconstructedCall.getId()).isEqualTo(id);
assertThat(reconstructedCall.getCallerId()).isEqualTo(callerId);
@@ -60,6 +60,7 @@ public class CallMetadataSyncDataTest {
assertThat(reconstructedCall.getFacilitator().getName()).isEqualTo(appName);
assertThat(reconstructedCall.getFacilitator().getIdentifier()).isEqualTo(appIdentifier);
assertThat(reconstructedCall.getStatus()).isEqualTo(status);
+ assertThat(reconstructedCall.getDirection()).isEqualTo(direction);
assertThat(reconstructedCall.getControls()).containsExactly(control1, control2);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
index 6a939ab34768..201d8f9413a2 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
@@ -149,6 +149,27 @@ public class CrossDeviceCallTest {
}
@Test
+ public void updateCallDetails_transitionDialingToOngoing() {
+ final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
+ InstrumentationRegistry.getTargetContext(),
+ mUninitializedCallDetails, /* callAudioState= */ null);
+ crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_DIALING,
+ Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
+ assertWithMessage("Wrong status for dialing state").that(crossDeviceCall.getStatus())
+ .isEqualTo(android.companion.Telecom.Call.DIALING);
+ assertWithMessage("Wrong controls for dialing state").that(crossDeviceCall.getControls())
+ .isEqualTo(Set.of(android.companion.Telecom.END));
+ crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_ACTIVE,
+ Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
+ assertWithMessage("Wrong status for active state").that(crossDeviceCall.getStatus())
+ .isEqualTo(android.companion.Telecom.Call.ONGOING);
+ assertWithMessage("Wrong controls for active state").that(crossDeviceCall.getControls())
+ .isEqualTo(Set.of(android.companion.Telecom.END,
+ android.companion.Telecom.MUTE,
+ android.companion.Telecom.PUT_ON_HOLD));
+ }
+
+ @Test
public void updateSilencedIfRinging_ringing_silenced() {
final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
InstrumentationRegistry.getTargetContext(),
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
index 7688fcb2faba..7e392a4261c1 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
@@ -162,13 +162,31 @@ public class CrossDeviceSyncControllerTest {
}
@Test
- public void createPhoneAccount_success() {
+ public void createPhoneAccount_sip_success() {
final PhoneAccount phoneAccount =
CrossDeviceSyncController.PhoneAccountManager.createPhoneAccount(
new PhoneAccountHandle(
new ComponentName("com.google.test", "com.google.test.Activity"),
- "id"), "Test App", "com.google.test");
+ "id"), "Test App", "com.google.test", 1, false);
assertWithMessage("Could not create phone account").that(phoneAccount).isNotNull();
+ assertWithMessage("Wrong schemes supported; should not support TEL")
+ .that(phoneAccount.supportsUriScheme(PhoneAccount.SCHEME_TEL)).isFalse();
+ assertWithMessage("Wrong schemes supported; should support SIP")
+ .that(phoneAccount.supportsUriScheme(PhoneAccount.SCHEME_SIP)).isTrue();
+ }
+
+ @Test
+ public void createPhoneAccount_tel_success() {
+ final PhoneAccount phoneAccount =
+ CrossDeviceSyncController.PhoneAccountManager.createPhoneAccount(
+ new PhoneAccountHandle(
+ new ComponentName("com.google.test", "com.google.test.Activity"),
+ "id"), "Test App", "com.google.test", 1, true);
+ assertWithMessage("Could not create phone account").that(phoneAccount).isNotNull();
+ assertWithMessage("Wrong schemes supported; should support TEL")
+ .that(phoneAccount.supportsUriScheme(PhoneAccount.SCHEME_TEL)).isTrue();
+ assertWithMessage("Wrong schemes supported; should not support SIP")
+ .that(phoneAccount.supportsUriScheme(PhoneAccount.SCHEME_SIP)).isFalse();
}
@Test
@@ -214,9 +232,10 @@ public class CrossDeviceSyncControllerTest {
}
@Test
- public void updateCalls_newCall() {
+ public void updateCalls_newIncomingCall_added() {
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.INCOMING);
call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
@@ -225,25 +244,133 @@ public class CrossDeviceSyncControllerTest {
new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
verify(mMockTelecomManager, times(1)).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
+ }
+
+ @Test
+ public void updateCalls_newOutgoingCall_added() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setCallerId("555-555-5555");
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, times(1)).placeCall(any(), any());
+ }
+
+ @Test
+ public void updateCalls_newOutgoingCall_noAddress_notAdded() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
}
@Test
- public void updateCalls_newCall_noFacilitator() {
+ public void updateCalls_newIncomingCall_noFacilitator_notAdded() {
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.INCOMING);
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
new CrossDeviceSyncController.CallManager(mMockContext,
new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
- verify(mMockTelecomManager, times(0)).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
}
@Test
- public void updateCalls_existingCall() {
+ public void updateCalls_newOutgoingCall_noFacilitator_notAdded() {
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setCallerId("555-555-5555");
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
+ }
+
+ @Test
+ public void updateCalls_newIncomingCall_isSelfOwned_notAdded() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc::originalId");
+ call.setDirection(android.companion.Telecom.Call.INCOMING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.addSelfOwnedCallId("originalId");
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
+ }
+
+
+ @Test
+ public void updateCalls_newOutgoingCall_isSelfOwned_notAdded() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc::originalId");
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setCallerId("555-555-5555");
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.addSelfOwnedCallId("originalId");
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
+ }
+
+ @Test
+ public void updateCalls_existingIncomingCall() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.INCOMING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+ callMetadataSyncData.addCall(call);
+ final CrossDeviceSyncController.CallManager callManager =
+ new CrossDeviceSyncController.CallManager(mMockContext,
+ new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+ callManager.mCallIds.put(/* associationId= */ 0, Set.of(call.getId()));
+ callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+ verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
+ }
+
+ @Test
+ public void updateCalls_existingOutgoingCall() {
+ final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+ call.setId("123abc");
+ call.setDirection(android.companion.Telecom.Call.OUTGOING);
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setCallerId("555-555-5555");
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
@@ -252,6 +379,7 @@ public class CrossDeviceSyncControllerTest {
callManager.mCallIds.put(/* associationId= */ 0, Set.of(call.getId()));
callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
}
@Test
@@ -266,6 +394,7 @@ public class CrossDeviceSyncControllerTest {
callManager.mCallIds.put(/* associationId= */ 0, Set.of(call.getId(), "fakeCallId"));
callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+ verify(mMockTelecomManager, never()).placeCall(any(), any());
assertWithMessage("Hasn't removed the id of the removed call")
.that(callManager.mCallIds)
.containsExactly(/* associationId= */ 0, Set.of(call.getId()));
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
new file mode 100644
index 000000000000..c872a11e7988
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.contentcapture;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.ContentCaptureOptions;
+import android.content.Context;
+import android.content.pm.UserInfo;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Test for {@link ContentCaptureManagerService}.
+ *
+ * <p>Run with: {@code atest
+ * FrameworksServicesTests:com.android.server.contentcapture.ContentCaptureManagerServiceTest}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SuppressWarnings("GuardedBy") // Service not really running, no need to expose locks
+public class ContentCaptureManagerServiceTest {
+
+ private static final int USER_ID = 1234;
+
+ private static final String PACKAGE_NAME = "com.test.package";
+
+ private static final Context sContext = ApplicationProvider.getApplicationContext();
+
+ @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock private UserManagerInternal mMockUserManagerInternal;
+
+ private ContentCaptureManagerService mContentCaptureManagerService;
+
+ @Before
+ public void setup() {
+ when(mMockUserManagerInternal.getUserInfos()).thenReturn(new UserInfo[0]);
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
+ LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal);
+ mContentCaptureManagerService = new ContentCaptureManagerService(sContext);
+ }
+
+ @Test
+ public void getOptions_notAllowlisted() {
+ ContentCaptureOptions actual =
+ mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions(
+ USER_ID, PACKAGE_NAME);
+
+ assertThat(actual).isNull();
+ }
+
+ @Test
+ public void getOptions_allowlisted_contentCaptureReceiver() {
+ mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist(
+ USER_ID, ImmutableList.of(PACKAGE_NAME), /* components= */ null);
+
+ ContentCaptureOptions actual =
+ mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions(
+ USER_ID, PACKAGE_NAME);
+
+ assertThat(actual).isNotNull();
+ assertThat(actual.enableReceiver).isTrue();
+ assertThat(actual.contentProtectionOptions.enableReceiver).isFalse();
+ assertThat(actual.whitelistedComponents).isNull();
+ }
+
+ @Test
+ public void getOptions_allowlisted_bothReceivers() {
+ mContentCaptureManagerService.mDevCfgEnableContentProtectionReceiver = true;
+ mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist(
+ USER_ID, ImmutableList.of(PACKAGE_NAME), /* components= */ null);
+
+ ContentCaptureOptions actual =
+ mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions(
+ USER_ID, PACKAGE_NAME);
+
+ assertThat(actual).isNotNull();
+ assertThat(actual.enableReceiver).isTrue();
+ assertThat(actual.contentProtectionOptions.enableReceiver).isTrue();
+ assertThat(actual.whitelistedComponents).isNull();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/OWNERS b/services/tests/servicestests/src/com/android/server/contentcapture/OWNERS
new file mode 100644
index 000000000000..b3583a7f6ab1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 544200
+
+include /core/java/android/view/contentcapture/OWNERS
+
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/OWNERS b/services/tests/servicestests/src/com/android/server/contentprotection/OWNERS
new file mode 100644
index 000000000000..24561c59bba6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 544200
+
+include /core/java/android/view/contentcapture/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
new file mode 100644
index 000000000000..2f57fd37194e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.contentprotection;
+
+import static android.view.contentcapture.ContentCaptureSession.FLUSH_REASON_LOGIN_DETECTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.os.UserHandle;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.IContentCaptureDirectManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.infra.ServiceConnector;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+/**
+ * Test for {@link RemoteContentProtectionService}.
+ *
+ * <p>Run with: {@code atest
+ * FrameworksServicesTests:com.android.server.contentprotection.RemoteContentProtectionServiceTest}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RemoteContentProtectionServiceTest {
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock private IContentCaptureDirectManager mMockContentCaptureDirectManager;
+
+ private RemoteContentProtectionService mRemoteContentProtectionService;
+
+ private int mConnectCallCount = 0;
+
+ @Before
+ public void setup() {
+ ComponentName componentName = new ComponentName(mContext.getPackageName(), "TestClass");
+ mRemoteContentProtectionService =
+ new TestRemoteContentProtectionService(mContext, componentName);
+ }
+
+ @Test
+ public void doesNotAutoConnect() {
+ assertThat(mConnectCallCount).isEqualTo(0);
+ verifyZeroInteractions(mMockContentCaptureDirectManager);
+ }
+
+ @Test
+ public void getAutoDisconnectTimeoutMs() {
+ long actual = mRemoteContentProtectionService.getAutoDisconnectTimeoutMs();
+
+ assertThat(actual).isEqualTo(3000L);
+ }
+
+ @Test
+ public void onLoginDetected() throws Exception {
+ ContentCaptureEvent event =
+ new ContentCaptureEvent(/* sessionId= */ 1111, /* type= */ 2222);
+ ParceledListSlice<ContentCaptureEvent> events =
+ new ParceledListSlice<>(ImmutableList.of(event));
+
+ mRemoteContentProtectionService.onLoginDetected(events);
+
+ verify(mMockContentCaptureDirectManager)
+ .sendEvents(events, FLUSH_REASON_LOGIN_DETECTED, /* options= */ null);
+ }
+
+ private final class TestRemoteContentProtectionService extends RemoteContentProtectionService {
+
+ TestRemoteContentProtectionService(Context context, ComponentName componentName) {
+ super(context, componentName, UserHandle.myUserId(), /* bindAllowInstant= */ false);
+ }
+
+ @Override // from ServiceConnector
+ public synchronized AndroidFuture<IContentCaptureDirectManager> connect() {
+ mConnectCallCount++;
+ return AndroidFuture.completedFuture(mMockContentCaptureDirectManager);
+ }
+
+ @Override // from ServiceConnector
+ public boolean run(@NonNull ServiceConnector.VoidJob<IContentCaptureDirectManager> job) {
+ try {
+ job.run(mMockContentCaptureDirectManager);
+ } catch (Exception ex) {
+ fail("Unexpected exception: " + ex);
+ }
+ return true;
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 39de2cf86a6c..99a3b808e082 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -7842,7 +7842,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
throws Exception {
int validLockTaskFeatures = LOCK_TASK_FEATURE_SYSTEM_INFO | LOCK_TASK_FEATURE_KEYGUARD
| LOCK_TASK_FEATURE_HOME | LOCK_TASK_FEATURE_GLOBAL_ACTIONS
- | LOCK_TASK_FEATURE_NOTIFICATIONS;
+ | LOCK_TASK_FEATURE_NOTIFICATIONS | LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK;
setDeviceOwner();
dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_FINANCED);
@@ -7857,7 +7857,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
public void testSetLockTaskFeatures_financeDo_invalidLockTaskFeatures_throwsException()
throws Exception {
int invalidLockTaskFeatures = LOCK_TASK_FEATURE_NONE | LOCK_TASK_FEATURE_OVERVIEW
- | LOCK_TASK_FEATURE_HOME | LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK;
+ | LOCK_TASK_FEATURE_HOME;
setDeviceOwner();
dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_FINANCED);
// Called during setup.
diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 3bef413a3e72..a6acd60f3bd7 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -85,7 +85,7 @@ public class AutomaticBrightnessControllerTest {
@Mock HysteresisLevels mAmbientBrightnessThresholdsIdle;
@Mock HysteresisLevels mScreenBrightnessThresholdsIdle;
@Mock Handler mNoOpHandler;
- @Mock HighBrightnessModeController mHbmController;
+ @Mock BrightnessRangeController mBrightnessRangeController;
@Mock BrightnessThrottler mBrightnessThrottler;
@Before
@@ -134,12 +134,15 @@ public class AutomaticBrightnessControllerTest {
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
mAmbientBrightnessThresholdsIdle, mScreenBrightnessThresholdsIdle,
- mContext, mHbmController, mBrightnessThrottler, mIdleBrightnessMappingStrategy,
- AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG, userLux, userBrightness
+ mContext, mBrightnessRangeController, mBrightnessThrottler,
+ mIdleBrightnessMappingStrategy, AMBIENT_LIGHT_HORIZON_SHORT,
+ AMBIENT_LIGHT_HORIZON_LONG, userLux, userBrightness
);
- when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT);
- when(mHbmController.getCurrentBrightnessMin()).thenReturn(BRIGHTNESS_MIN_FLOAT);
+ when(mBrightnessRangeController.getCurrentBrightnessMax()).thenReturn(
+ BRIGHTNESS_MAX_FLOAT);
+ when(mBrightnessRangeController.getCurrentBrightnessMin()).thenReturn(
+ BRIGHTNESS_MIN_FLOAT);
// Disable brightness throttling by default. Individual tests can enable it as needed.
when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
when(mBrightnessThrottler.isThrottled()).thenReturn(false);
@@ -473,6 +476,42 @@ public class AutomaticBrightnessControllerTest {
}
@Test
+ public void testSwitchBetweenModesNoUserInteractions() throws Exception {
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ // Sensor reads 123 lux,
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 123));
+ when(mBrightnessMappingStrategy.getShortTermModelTimeout()).thenReturn(2000L);
+ when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1.0f);
+ when(mBrightnessMappingStrategy.getUserLux()).thenReturn(-1.0f);
+
+ // No user brightness interaction.
+
+ mController.switchToIdleMode();
+ when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true);
+ when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1.0f);
+ when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(-1.0f);
+
+ // Sensor reads 1000 lux,
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1000));
+ // Do not fast-forward time.
+ mTestLooper.dispatchAll();
+
+ mController.switchToInteractiveScreenBrightnessMode();
+ // Do not fast-forward time
+ mTestLooper.dispatchAll();
+
+ // Ensure that there are no data points added, since the user has never adjusted the
+ // brightness
+ verify(mBrightnessMappingStrategy, times(0))
+ .addUserDataPoint(anyFloat(), anyFloat());
+ }
+
+ @Test
public void testSwitchToIdleMappingStrategy() throws Exception {
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index a6c57371803b..0e775d57bbd7 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -35,12 +35,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -72,6 +74,7 @@ import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
+import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.MessageQueue;
@@ -96,17 +99,18 @@ import com.android.internal.R;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
+import com.android.server.display.DisplayManagerService.DeviceStateListener;
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.input.InputManagerInternal;
import com.android.server.lights.LightsManager;
import com.android.server.sensors.SensorManagerInternal;
import com.android.server.wm.WindowManagerInternal;
-import com.google.common.collect.ImmutableMap;
-
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+import com.google.common.collect.ImmutableMap;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -114,6 +118,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -547,6 +552,30 @@ public class DisplayManagerServiceTest {
}
/**
+ * Tests that we send the device state to window manager
+ */
+ @Test
+ public void testOnStateChanged_sendsStateChangedEventToWm() throws Exception {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mShortMockedInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+ displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ DeviceStateListener listener = displayManager.new DeviceStateListener();
+ Handler handler = displayManager.getDisplayHandler();
+ IDisplayManagerCallback displayChangesCallback = registerDisplayChangeCallback(
+ displayManager);
+
+ listener.onStateChanged(123);
+ waitForIdleHandler(handler);
+
+ InOrder inOrder = inOrder(mMockWindowManagerInternal, displayChangesCallback);
+ // Verify there are no display events before WM call
+ inOrder.verify(displayChangesCallback, never()).onDisplayEvent(anyInt(), anyInt());
+ inOrder.verify(mMockWindowManagerInternal).onDisplayManagerReceivedDeviceState(123);
+ }
+
+ /**
* Tests that there should be a display change notification to WindowManager to update its own
* internal state for things like display cutout when nonOverrideDisplayInfo is changed.
*/
@@ -2054,6 +2083,15 @@ public class DisplayManagerServiceTest {
updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
}
+ private IDisplayManagerCallback registerDisplayChangeCallback(
+ DisplayManagerService displayManager) {
+ IDisplayManagerCallback displayChangesCallback = mock(IDisplayManagerCallback.class);
+ when(displayChangesCallback.asBinder()).thenReturn(new Binder());
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ binderService.registerCallback(displayChangesCallback);
+ return displayChangesCallback;
+ }
+
private FakeDisplayManagerCallback registerDisplayListenerCallback(
DisplayManagerService displayManager,
DisplayManagerService.BinderService displayManagerBinderService,
diff --git a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
index 817b245a78bf..642f54c25a46 100644
--- a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -60,6 +60,114 @@ public class PersistentDataStoreTest {
}
@Test
+ public void testLoadBrightness() {
+ final String uniqueDisplayId = "test:123";
+ final DisplayDevice testDisplayDevice = new DisplayDevice(
+ null, null, uniqueDisplayId, null) {
+ @Override
+ public boolean hasStableUniqueId() {
+ return true;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return null;
+ }
+ };
+
+ String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<display-manager-state>\n"
+ + " <display-states>\n"
+ + " <display unique-id=\"test:123\">\n"
+ + " <brightness-value user-serial=\"1\">0.1</brightness-value>\n"
+ + " <brightness-value user-serial=\"2\">0.2</brightness-value>\n"
+ + " </display>\n"
+ + " </display-states>\n"
+ + "</display-manager-state>\n";
+
+ InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+ mInjector.setReadStream(is);
+ mDataStore.loadIfNeeded();
+
+ float brightness = mDataStore.getBrightness(testDisplayDevice, 1);
+ assertEquals(0.1, brightness, 0.01);
+
+ brightness = mDataStore.getBrightness(testDisplayDevice, 2);
+ assertEquals(0.2, brightness, 0.01);
+ }
+
+ @Test
+ public void testSetBrightness_brightnessTagWithNoUserId_updatesToBrightnessTagWithUserId() {
+ final String uniqueDisplayId = "test:123";
+ final DisplayDevice testDisplayDevice =
+ new DisplayDevice(null, null, uniqueDisplayId, null) {
+ @Override
+ public boolean hasStableUniqueId() {
+ return true;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return null;
+ }
+ };
+
+ String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<display-manager-state>\n"
+ + " <display-states>\n"
+ + " <color-mode>0</color-mode>\n"
+ + " <display unique-id=\"test:123\">\n"
+ + " <brightness-value>0.5</brightness-value>\n"
+ + " </display>\n"
+ + " </display-states>\n"
+ + "</display-manager-state>\n";
+
+ InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+ mInjector.setReadStream(is);
+ mDataStore.loadIfNeeded();
+
+ float user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ float user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertEquals(0.5, user1Brightness, 0.01);
+ assertEquals(0.5, user2Brightness, 0.01);
+
+ // Override the value for user 2. Default user must have been removed.
+ mDataStore.setBrightness(testDisplayDevice, 0.2f, 2 /* userSerial */ /* brightness*/);
+
+ user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertTrue(Float.isNaN(user1Brightness));
+ assertEquals(0.2f, user2Brightness, 0.01);
+
+ // Override the value for user 1. User-specific brightness values should co-exist.
+ mDataStore.setBrightness(testDisplayDevice, 0.1f, 1 /* userSerial */ /* brightness*/);
+ user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertEquals(0.1f, user1Brightness, 0.01);
+ assertEquals(0.2f, user2Brightness, 0.01);
+
+ // Validate saveIfNeeded writes user-specific brightnes.
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mInjector.setWriteStream(baos);
+ mDataStore.saveIfNeeded();
+ mTestLooper.dispatchAll();
+ assertTrue(mInjector.wasWriteSuccessful());
+ TestInjector newInjector = new TestInjector();
+ PersistentDataStore newDataStore = new PersistentDataStore(newInjector);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ newInjector.setReadStream(bais);
+ newDataStore.loadIfNeeded();
+
+ user1Brightness = newDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = newDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ float unknownUserBrightness =
+ newDataStore.getBrightness(testDisplayDevice, 999 /* userSerial */);
+ assertEquals(0.1f, user1Brightness, 0.01);
+ assertEquals(0.2f, user2Brightness, 0.01);
+ assertTrue(Float.isNaN(unknownUserBrightness));
+ }
+
+ @Test
public void testLoadingBrightnessConfigurations() {
String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<display-manager-state>\n"
@@ -374,7 +482,7 @@ public class PersistentDataStoreTest {
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
newInjector.setReadStream(bais);
newDataStore.loadIfNeeded();
- assertTrue(Float.isNaN(mDataStore.getBrightness(testDisplayDevice)));
+ assertTrue(Float.isNaN(mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */)));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index e6d3bbc53c83..c4f483810478 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -19,6 +19,7 @@ package com.android.server.display.brightness;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -247,6 +248,7 @@ public final class DisplayBrightnessControllerTest {
0.0f);
verify(mBrightnessChangeExecutor).execute(mOnBrightnessChangeRunnable);
verify(mBrightnessSetting).setBrightness(brightnessValue);
+ verify(mBrightnessSetting).setUserSerial(anyInt());
// Does nothing if the value is invalid
mDisplayBrightnessController.updateScreenBrightnessSetting(Float.NaN);
@@ -358,4 +360,28 @@ public final class DisplayBrightnessControllerTest {
verify(mBrightnessSetting, never()).getBrightnessNitsForDefaultDisplay();
verify(mBrightnessSetting, never()).setBrightness(brightness);
}
+
+ @Test
+ public void testChangeBrightnessNitsWhenUserChanges() {
+ float brightnessValue1 = 0.3f;
+ float nits1 = 200f;
+ float brightnessValue2 = 0.5f;
+ float nits2 = 300f;
+ AutomaticBrightnessController automaticBrightnessController =
+ mock(AutomaticBrightnessController.class);
+ when(automaticBrightnessController.convertToNits(brightnessValue1)).thenReturn(nits1);
+ when(automaticBrightnessController.convertToNits(brightnessValue2)).thenReturn(nits2);
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ automaticBrightnessController);
+
+ mDisplayBrightnessController.setBrightness(brightnessValue1, 1 /* user-serial */);
+ verify(mBrightnessSetting).setUserSerial(1);
+ verify(mBrightnessSetting).setBrightness(brightnessValue1);
+ verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits1);
+
+ mDisplayBrightnessController.setBrightness(brightnessValue2, 2 /* user-serial */);
+ verify(mBrightnessSetting).setUserSerial(2);
+ verify(mBrightnessSetting).setBrightness(brightnessValue2);
+ verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits2);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 0e6b412e330d..39930bc1e35a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -92,6 +92,7 @@ public class HdmiControlServiceTest {
private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
private HdmiPortInfo[] mHdmiPortInfo;
private ArrayList<Integer> mLocalDeviceTypes = new ArrayList<>();
+ private static final int PORT_ID_EARC_SUPPORTED = 3;
@Before
public void setUp() throws Exception {
@@ -148,7 +149,7 @@ public class HdmiControlServiceTest {
.setEarcSupported(false)
.build();
mHdmiPortInfo[2] =
- new HdmiPortInfo.Builder(3, HdmiPortInfo.PORT_INPUT, 0x2000)
+ new HdmiPortInfo.Builder(PORT_ID_EARC_SUPPORTED, HdmiPortInfo.PORT_INPUT, 0x2000)
.setCecSupported(true)
.setMhlSupported(false)
.setArcSupported(true)
@@ -1129,6 +1130,23 @@ public class HdmiControlServiceTest {
}
@Test
+ public void disableEarc_noEarcLocalDevice_enableArc() {
+ mHdmiControlServiceSpy.clearEarcLocalDevice();
+ mHdmiControlServiceSpy.addEarcLocalDevice(
+ new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy));
+ mHdmiControlServiceSpy.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlServiceSpy.getEarcLocalDevice()).isNull();
+
+ Mockito.clearInvocations(mHdmiControlServiceSpy);
+ mHdmiControlServiceSpy.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING,
+ PORT_ID_EARC_SUPPORTED);
+ verify(mHdmiControlServiceSpy, times(1))
+ .notifyEarcStatusToAudioService(eq(false), eq(new ArrayList<>()));
+ verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(true), any());
+ }
+
+ @Test
public void disableCec_doNotClearEarcLocalDevice() {
mHdmiControlServiceSpy.clearEarcLocalDevice();
mHdmiControlServiceSpy.addEarcLocalDevice(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java
new file mode 100644
index 000000000000..920c376d5dfb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.os.Looper;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Collections;
+
+/**
+ * TV specific tests for {@link HdmiControlService} class.
+ */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class HdmiControlServiceTvTest {
+
+ private static final String TAG = "HdmiControlServiceTvTest";
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private FakeNativeWrapper mNativeWrapper;
+ private HdmiEarcController mHdmiEarcController;
+ private FakeEarcNativeWrapper mEarcNativeWrapper;
+ private Looper mMyLooper;
+ private TestLooper mTestLooper = new TestLooper();
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+ mMyLooper = mTestLooper.getLooper();
+
+ FakeAudioFramework audioFramework = new FakeAudioFramework();
+
+ mHdmiControlService =
+ new HdmiControlService(InstrumentationRegistry.getTargetContext(),
+ Collections.singletonList(HdmiDeviceInfo.DEVICE_TV),
+ audioFramework.getAudioManager(),
+ audioFramework.getAudioDeviceVolumeManager()) {
+ @Override
+ int pathToPortId(int path) {
+ return Constants.INVALID_PORT_ID + 1;
+ }
+ };
+
+ mMyLooper = mTestLooper.getLooper();
+ mHdmiControlService.setIoLooper(mMyLooper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
+
+ mNativeWrapper = new FakeNativeWrapper();
+ mHdmiCecController = HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mEarcNativeWrapper = new FakeEarcNativeWrapper();
+ mHdmiEarcController = HdmiEarcController.createWithNativeWrapper(
+ mHdmiControlService, mEarcNativeWrapper);
+ mHdmiControlService.setEarcController(mHdmiEarcController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(
+ mHdmiControlService));
+ mHdmiControlService.initService();
+
+ mTestLooper.dispatchAll();
+ }
+
+ @Test
+ public void onCecMessage_shortPhysicalAddress_featureAbortInvalidOperand() {
+ // Invalid <Inactive Source> message.
+ HdmiCecMessage message = HdmiUtils.buildMessage("40:9D:14");
+
+ mNativeWrapper.onCecMessage(message);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ Constants.ADDR_TV, Constants.ADDR_PLAYBACK_1, Constants.MESSAGE_INACTIVE_SOURCE,
+ Constants.ABORT_INVALID_OPERAND);
+ assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
+ }
+
+ @Test
+ public void handleCecCommand_shortPhysicalAddress_returnsAbortInvalidOperand() {
+ // Invalid <Active Source> message.
+ HdmiCecMessage message = HdmiUtils.buildMessage("4F:82:10");
+
+ // In case of a broadcasted message <Feature Abort> is not expected.
+ // See CEC 1.4b specification, 12.2 Protocol General Rules for detail.
+ assertThat(mHdmiControlService.handleCecCommand(message))
+ .isEqualTo(Constants.ABORT_INVALID_OPERAND);
+ }
+
+ @Test
+ public void test_verifyPhysicalAddresses() {
+ // <Routing Change>
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("0F:80:10:00:40:00"))).isTrue();
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("0F:80:10:00:40"))).isFalse();
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("0F:80:10"))).isFalse();
+
+ // <System Audio Mode Request>
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("40:70:00:00"))).isTrue();
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("40:70:00"))).isFalse();
+
+ // <Active Source>
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("4F:82:10:00"))).isTrue();
+ assertThat(mHdmiControlService
+ .verifyPhysicalAddresses(HdmiUtils.buildMessage("4F:82:10"))).isFalse();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
index 272679280a62..ef15ccba4c74 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
@@ -32,7 +32,8 @@ import android.platform.test.annotations.Presubmit
import android.view.InputDevice
import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
-import com.android.server.input.KeyboardBacklightController.BRIGHTNESS_VALUE_FOR_LEVEL
+import com.android.server.input.KeyboardBacklightController.DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL
+import com.android.server.input.KeyboardBacklightController.MAX_BRIGHTNESS_CHANGE_STEPS
import com.android.server.input.KeyboardBacklightController.USER_INACTIVITY_THRESHOLD_MILLIS
import org.junit.After
import org.junit.Assert.assertEquals
@@ -65,12 +66,20 @@ private fun createKeyboard(deviceId: Int): InputDevice =
.build()
private fun createLight(lightId: Int, lightType: Int): Light =
+ createLight(
+ lightId,
+ lightType,
+ null
+ )
+
+private fun createLight(lightId: Int, lightType: Int, suggestedBrightnessLevels: IntArray?): Light =
Light(
lightId,
"Light $lightId",
1,
lightType,
- Light.LIGHT_CAPABILITY_BRIGHTNESS
+ Light.LIGHT_CAPABILITY_BRIGHTNESS,
+ suggestedBrightnessLevels
)
/**
* Tests for {@link KeyboardBacklightController}.
@@ -98,7 +107,6 @@ class KeyboardBacklightControllerTests {
private lateinit var context: Context
private lateinit var dataStore: PersistentDataStore
private lateinit var testLooper: TestLooper
- private val totalLevels = BRIGHTNESS_VALUE_FOR_LEVEL.size
private var lightColorMap: HashMap<Int, Int> = HashMap()
private var lastBacklightState: KeyboardBacklightState? = null
private var sysfsNodeChanges = 0
@@ -146,84 +154,21 @@ class KeyboardBacklightControllerTests {
@Test
fun testKeyboardBacklightIncrementDecrement() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
- for (level in 1 until totalLevels) {
- incrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for level $level mismatched",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for level $level must be correctly stored in the datastore",
- BRIGHTNESS_VALUE_FOR_LEVEL[level],
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
- }
-
- // Increment above max level
- incrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for max level mismatched",
- Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for max level must be correctly stored in the datastore",
- MAX_BRIGHTNESS,
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
-
- for (level in totalLevels - 2 downTo 0) {
- decrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for level $level mismatched",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for level $level must be correctly stored in the datastore",
- BRIGHTNESS_VALUE_FOR_LEVEL[level],
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
- }
-
- // Decrement below min level
- decrementKeyboardBacklight(DEVICE_ID)
- assertEquals(
- "Light value for min level mismatched",
- Color.argb(0, 0, 0, 0),
- lightColorMap[LIGHT_ID]
- )
- assertEquals(
- "Light value for min level must be correctly stored in the datastore",
- 0,
- dataStore.getKeyboardBacklightBrightness(
- keyboardWithBacklight.descriptor,
- LIGHT_ID
- ).asInt
- )
+ assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight,
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL)
}
}
@Test
fun testKeyboardWithoutBacklight() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithoutBacklight = createKeyboard(DEVICE_ID)
val keyboardInputLight = createLight(LIGHT_ID, Light.LIGHT_TYPE_INPUT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithoutBacklight)
@@ -237,7 +182,7 @@ class KeyboardBacklightControllerTests {
@Test
fun testKeyboardWithMultipleLight() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
val keyboardInputLight = createLight(SECOND_LIGHT_ID, Light.LIGHT_TYPE_INPUT)
@@ -259,17 +204,17 @@ class KeyboardBacklightControllerTests {
@Test
fun testRestoreBacklightOnInputDeviceAdded() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
- for (level in 1 until totalLevels) {
+ for (level in 1 until DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size) {
dataStore.setKeyboardBacklightBrightness(
keyboardWithBacklight.descriptor,
LIGHT_ID,
- BRIGHTNESS_VALUE_FOR_LEVEL[level] - 1
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[level] - 1
)
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
@@ -278,7 +223,7 @@ class KeyboardBacklightControllerTests {
assertEquals(
"Keyboard backlight level should be restored to the level saved in the " +
"data store",
- Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+ Color.argb(DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
lightColorMap[LIGHT_ID]
)
keyboardBacklightController.onInputDeviceRemoved(DEVICE_ID)
@@ -288,7 +233,7 @@ class KeyboardBacklightControllerTests {
@Test
fun testRestoreBacklightOnInputDeviceChanged() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
@@ -320,9 +265,10 @@ class KeyboardBacklightControllerTests {
@Test
fun testKeyboardBacklight_registerUnregisterListener() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
+ val maxLevel = DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL.size - 1
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
`when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
@@ -341,13 +287,13 @@ class KeyboardBacklightControllerTests {
lastBacklightState!!.deviceId
)
assertEquals(
- "Backlight state brightnessLevel should be " + 1,
+ "Backlight state brightnessLevel should be 1",
1,
lastBacklightState!!.brightnessLevel
)
assertEquals(
- "Backlight state maxBrightnessLevel should be " + (totalLevels - 1),
- (totalLevels - 1),
+ "Backlight state maxBrightnessLevel should be $maxLevel",
+ maxLevel,
lastBacklightState!!.maxBrightnessLevel
)
assertEquals(
@@ -368,7 +314,7 @@ class KeyboardBacklightControllerTests {
@Test
fun testKeyboardBacklight_userActivity() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
@@ -400,7 +346,7 @@ class KeyboardBacklightControllerTests {
@Test
fun testKeyboardBacklight_displayOnOff() {
- BacklightAnimationFlag(false).use {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
@@ -490,7 +436,7 @@ class KeyboardBacklightControllerTests {
@Test
@UiThreadTest
fun testKeyboardBacklightAnimation_onChangeLevels() {
- BacklightAnimationFlag(true).use {
+ KeyboardBacklightFlags(animationEnabled = true, customLevelsEnabled = false).use {
val keyboardWithBacklight = createKeyboard(DEVICE_ID)
val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT)
`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
@@ -500,17 +446,145 @@ class KeyboardBacklightControllerTests {
incrementKeyboardBacklight(DEVICE_ID)
assertEquals(
"Should start animation from level 0",
- BRIGHTNESS_VALUE_FOR_LEVEL[0],
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[0],
lastAnimationValues[0]
)
assertEquals(
"Should start animation to level 1",
- BRIGHTNESS_VALUE_FOR_LEVEL[1],
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL[1],
lastAnimationValues[1]
)
}
}
+ @Test
+ fun testKeyboardBacklightPreferredLevels() {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = true).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val suggestedLevels = intArrayOf(0, 22, 63, 135, 196, 255)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT,
+ suggestedLevels)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight,
+ suggestedLevels)
+ }
+ }
+
+ @Test
+ fun testKeyboardBacklightPreferredLevels_moreThanMax_shouldUseDefault() {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = true).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val suggestedLevels = IntArray(MAX_BRIGHTNESS_CHANGE_STEPS + 1) { 10 * (it + 1) }
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT,
+ suggestedLevels)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight,
+ DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL)
+ }
+ }
+
+ @Test
+ fun testKeyboardBacklightPreferredLevels_mustHaveZeroAndMaxBrightnessAsBounds() {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = true).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val suggestedLevels = intArrayOf(22, 63, 135, 196)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT,
+ suggestedLevels)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ // Framework will add the lowest and maximum levels if not provided via config
+ assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight,
+ intArrayOf(0, 22, 63, 135, 196, 255))
+ }
+ }
+
+ @Test
+ fun testKeyboardBacklightPreferredLevels_dropsOutOfBoundsLevels() {
+ KeyboardBacklightFlags(animationEnabled = false, customLevelsEnabled = true).use {
+ val keyboardWithBacklight = createKeyboard(DEVICE_ID)
+ val suggestedLevels = intArrayOf(22, 63, 135, 400, 196, 1000)
+ val keyboardBacklight = createLight(LIGHT_ID, Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT,
+ suggestedLevels)
+ `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
+ `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
+ keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+
+ // Framework will drop out of bound levels in the config
+ assertIncrementDecrementForLevels(keyboardWithBacklight, keyboardBacklight,
+ intArrayOf(0, 22, 63, 135, 196, 255))
+ }
+ }
+
+ private fun assertIncrementDecrementForLevels(
+ device: InputDevice,
+ light: Light,
+ expectedLevels: IntArray
+ ) {
+ val deviceId = device.id
+ val lightId = light.id
+ for (level in 1 until expectedLevels.size) {
+ incrementKeyboardBacklight(deviceId)
+ assertEquals(
+ "Light value for level $level mismatched",
+ Color.argb(expectedLevels[level], 0, 0, 0),
+ lightColorMap[lightId]
+ )
+ assertEquals(
+ "Light value for level $level must be correctly stored in the datastore",
+ expectedLevels[level],
+ dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt
+ )
+ }
+
+ // Increment above max level
+ incrementKeyboardBacklight(deviceId)
+ assertEquals(
+ "Light value for max level mismatched",
+ Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
+ lightColorMap[lightId]
+ )
+ assertEquals(
+ "Light value for max level must be correctly stored in the datastore",
+ MAX_BRIGHTNESS,
+ dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt
+ )
+
+ for (level in expectedLevels.size - 2 downTo 0) {
+ decrementKeyboardBacklight(deviceId)
+ assertEquals(
+ "Light value for level $level mismatched",
+ Color.argb(expectedLevels[level], 0, 0, 0),
+ lightColorMap[lightId]
+ )
+ assertEquals(
+ "Light value for level $level must be correctly stored in the datastore",
+ expectedLevels[level],
+ dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt
+ )
+ }
+
+ // Decrement below min level
+ decrementKeyboardBacklight(deviceId)
+ assertEquals(
+ "Light value for min level mismatched",
+ Color.argb(0, 0, 0, 0),
+ lightColorMap[lightId]
+ )
+ assertEquals(
+ "Light value for min level must be correctly stored in the datastore",
+ 0,
+ dataStore.getKeyboardBacklightBrightness(device.descriptor, lightId).asInt
+ )
+ }
+
inner class KeyboardBacklightListener : IKeyboardBacklightListener.Stub() {
override fun onBrightnessChanged(
deviceId: Int,
@@ -545,9 +619,13 @@ class KeyboardBacklightControllerTests {
val isTriggeredByKeyPress: Boolean
)
- private inner class BacklightAnimationFlag constructor(enabled: Boolean) : AutoCloseable {
+ private inner class KeyboardBacklightFlags constructor(
+ animationEnabled: Boolean,
+ customLevelsEnabled: Boolean
+ ) : AutoCloseable {
init {
- InputFeatureFlagProvider.setKeyboardBacklightAnimationEnabled(enabled)
+ InputFeatureFlagProvider.setKeyboardBacklightAnimationEnabled(animationEnabled)
+ InputFeatureFlagProvider.setKeyboardBacklightCustomLevelsEnabled(customLevelsEnabled)
}
override fun close() {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
index 2b49b8ab64d2..a242cdec89db 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
@@ -23,6 +23,8 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import android.app.PropertyInvalidatedCache;
import android.app.admin.DevicePolicyManager;
@@ -38,8 +40,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.nio.ByteBuffer;
-/** Test setting a lockscreen credential and then verify it under USER_FRP */
+/** Tests that involve the Factory Reset Protection (FRP) credential. */
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -148,4 +151,68 @@ public class LockscreenFrpTest extends BaseLockSettingsServiceTests {
mService.verifyCredential(newPin("1234"), USER_FRP, 0 /* flags */)
.getResponseCode());
}
+
+ // The FRP block that gets written by the current version of Android must still be accepted by
+ // old versions of Android. This test tries to detect non-forward-compatible changes in
+ // PasswordData#toBytes(), which would break that.
+ @Test
+ public void testFrpBlock_isForwardsCompatible() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+ PersistentData data = mStorage.readPersistentDataBlock();
+ ByteBuffer buffer = ByteBuffer.wrap(data.payload);
+
+ final int credentialType = buffer.getInt();
+ assertEquals(CREDENTIAL_TYPE_PIN, credentialType);
+
+ final byte scryptLogN = buffer.get();
+ assertTrue(scryptLogN >= 0);
+
+ final byte scryptLogR = buffer.get();
+ assertTrue(scryptLogR >= 0);
+
+ final byte scryptLogP = buffer.get();
+ assertTrue(scryptLogP >= 0);
+
+ final int saltLength = buffer.getInt();
+ assertTrue(saltLength > 0);
+ final byte[] salt = new byte[saltLength];
+ buffer.get(salt);
+
+ final int passwordHandleLength = buffer.getInt();
+ assertTrue(passwordHandleLength > 0);
+ final byte[] passwordHandle = new byte[passwordHandleLength];
+ buffer.get(passwordHandle);
+ }
+
+ @Test
+ public void testFrpBlock_inBadAndroid14FormatIsAutomaticallyFixed() {
+ mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+
+ // Write a "bad" FRP block with PasswordData beginning with the bytes [0, 2].
+ byte[] badPasswordData = new byte[] {
+ 0, 2, /* version 2 */
+ 0, 3, /* CREDENTIAL_TYPE_PIN */
+ 11, /* scryptLogN */
+ 22, /* scryptLogR */
+ 33, /* scryptLogP */
+ 0, 0, 0, 5, /* salt.length */
+ 1, 2, -1, -2, 55, /* salt */
+ 0, 0, 0, 6, /* passwordHandle.length */
+ 2, 3, -2, -3, 44, 1, /* passwordHandle */
+ 0, 0, 0, 6, /* pinLength */
+ };
+ mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_GATEKEEPER, PRIMARY_USER_ID, 0,
+ badPasswordData);
+
+ // Execute the code that should fix the FRP block.
+ assertFalse(mStorage.getBoolean("migrated_frp2", false, 0));
+ mService.migrateOldDataAfterSystemReady();
+ assertTrue(mStorage.getBoolean("migrated_frp2", false, 0));
+
+ // Verify that the FRP block has been fixed.
+ PersistentData data = mStorage.readPersistentDataBlock();
+ assertEquals(PersistentData.TYPE_SP_GATEKEEPER, data.type);
+ ByteBuffer buffer = ByteBuffer.wrap(data.payload);
+ assertEquals(CREDENTIAL_TYPE_PIN, buffer.getInt());
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 067feae4d36a..ce0347dbe4ac 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -638,6 +638,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
2, 3, -2, -3, 44, 1, /* passwordHandle */
0, 0, 0, 6, /* pinLength */
};
+ assertFalse(PasswordData.isBadFormatFromAndroid14Beta(serialized));
PasswordData deserialized = PasswordData.fromBytes(serialized);
assertEquals(11, deserialized.scryptLogN);
@@ -690,6 +691,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
2, 3, -2, -3, 44, 1, /* passwordHandle */
0, 0, 0, 6, /* pinLength */
};
+ assertTrue(PasswordData.isBadFormatFromAndroid14Beta(serialized));
PasswordData deserialized = PasswordData.fromBytes(serialized);
assertEquals(11, deserialized.scryptLogN);
diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
index 849aae29aca0..2f039654ca7e 100644
--- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
@@ -34,7 +34,10 @@ import android.hardware.SensorManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.BatteryStats;
import android.os.Handler;
+import android.os.IWakeLockCallback;
import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.VibrationAttributes;
import android.os.Vibrator;
@@ -219,6 +222,34 @@ public class NotifierTest {
verify(mStatusBarManagerInternal, never()).showChargingAnimation(anyInt());
}
+ @Test
+ public void testOnWakeLockListener_RemoteException_NoRethrow() {
+ createNotifier();
+
+ IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+ @Override public void onStateChanged(boolean enabled) throws RemoteException {
+ throw new RemoteException("Just testing");
+ }
+ };
+
+ final int uid = 1234;
+ final int pid = 5678;
+ mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+ exceptingCallback);
+ mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+ exceptingCallback);
+ mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+ exceptingCallback,
+ PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+ "my.package.name", uid, pid, /* newWorkSource= */ null, /* newHistoryTag= */ null,
+ exceptingCallback);
+ mTestLooper.dispatchAll();
+ // If we didn't throw, we're good!
+ }
+
private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() {
@Override
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 6ef81f6c6211..8f7f2f66308b 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -81,6 +81,7 @@ import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.No
import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE;
import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_UPDATED;
@@ -678,6 +679,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@After
public void assertAllTrackersFinishedOrCancelled() {
+ waitForIdle(); // Finish async work.
// Verify that no trackers were left dangling.
for (PostNotificationTracker tracker : mPostNotificationTrackerFactory.mCreatedTrackers) {
assertThat(tracker.isOngoing()).isFalse();
@@ -5618,6 +5620,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testVisitUris_publicVersion() throws Exception {
+ final Icon smallIconPublic = Icon.createWithContentUri("content://media/small/icon");
+ final Icon largeIconPrivate = Icon.createWithContentUri("content://media/large/icon");
+
+ Notification publicVersion = new Notification.Builder(mContext, "a")
+ .setContentTitle("notification with uris")
+ .setSmallIcon(smallIconPublic)
+ .build();
+ Notification n = new Notification.Builder(mContext, "a")
+ .setLargeIcon(largeIconPrivate)
+ .setPublicVersion(publicVersion)
+ .build();
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ n.visitUris(visitor);
+ verify(visitor, times(1)).accept(eq(smallIconPublic.getUri()));
+ verify(visitor, times(1)).accept(eq(largeIconPrivate.getUri()));
+ }
+
+ @Test
public void testVisitUris_audioContentsString() throws Exception {
final Uri audioContents = Uri.parse("content://com.example/audio");
@@ -11748,6 +11770,103 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertFalse(n.isUserInitiatedJob());
}
+ @Test
+ public void enqueue_updatesEnqueueRate() throws Exception {
+ Notification n = generateNotificationRecord(null).getNotification();
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+ // Don't waitForIdle() here. We want to verify the "intermediate" state.
+
+ verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+ verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ waitForIdle();
+ }
+
+ @Test
+ public void enqueue_withPost_updatesEnqueueRateAndPost() throws Exception {
+ Notification n = generateNotificationRecord(null).getNotification();
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+ waitForIdle();
+
+ verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+ verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+ verify(mUsageStats).registerPostedByApp(any());
+ }
+
+ @Test
+ public void enqueueNew_whenOverEnqueueRate_accepts() throws Exception {
+ Notification n = generateNotificationRecord(null).getNotification();
+ when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+ .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE + 1f);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+ waitForIdle();
+
+ assertThat(mService.mNotificationsByKey).hasSize(1);
+ verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+ verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+ verify(mUsageStats).registerPostedByApp(any());
+ }
+
+ @Test
+ public void enqueueUpdate_whenBelowMaxEnqueueRate_accepts() throws Exception {
+ // Post the first version.
+ Notification original = generateNotificationRecord(null).getNotification();
+ original.when = 111;
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, original, mUserId);
+ waitForIdle();
+ assertThat(mService.mNotificationList).hasSize(1);
+ assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111);
+
+ reset(mUsageStats);
+ when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+ .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE - 1f);
+
+ // Post the update.
+ Notification update = generateNotificationRecord(null).getNotification();
+ update.when = 222;
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, update, mUserId);
+ waitForIdle();
+
+ verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+ verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+ verify(mUsageStats, never()).registerPostedByApp(any());
+ verify(mUsageStats).registerUpdatedByApp(any(), any());
+ assertThat(mService.mNotificationList).hasSize(1);
+ assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(222);
+ }
+
+ @Test
+ public void enqueueUpdate_whenAboveMaxEnqueueRate_rejects() throws Exception {
+ // Post the first version.
+ Notification original = generateNotificationRecord(null).getNotification();
+ original.when = 111;
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, original, mUserId);
+ waitForIdle();
+ assertThat(mService.mNotificationList).hasSize(1);
+ assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111);
+
+ reset(mUsageStats);
+ when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+ .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE + 1f);
+
+ // Post the update.
+ Notification update = generateNotificationRecord(null).getNotification();
+ update.when = 222;
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, update, mUserId);
+ waitForIdle();
+
+ verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+ verify(mUsageStats, never()).registerEnqueuedByAppAndAccepted(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+ verify(mUsageStats, never()).registerUpdatedByApp(any(), any());
+ assertThat(mService.mNotificationList).hasSize(1);
+ assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111); // old
+ }
+
private void setDpmAppOppsExemptFromDismissal(boolean isOn) {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
index 27677e153d83..6668f8520820 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
@@ -87,9 +87,6 @@ public class NotificationVisitUrisTest extends UiServiceTestCase {
// This list should be emptied! Items can be removed as bugs are fixed.
private static final Multimap<Class<?>, String> KNOWN_BAD =
ImmutableMultimap.<Class<?>, String>builder()
- .put(Notification.Builder.class, "setPublicVersion") // b/276294099
- .putAll(RemoteViews.class, "addView", "addStableView") // b/277740082
- .put(RemoteViews.class, "setIcon") // b/281018094
.put(Notification.WearableExtender.class, "addAction") // TODO: b/281044385
.put(Person.Builder.class, "setUri") // TODO: b/281044385
.put(RemoteViews.class, "setRemoteAdapter") // TODO: b/281044385
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
index 68aa1dc1bf3b..4840f07285d6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
@@ -15,8 +15,9 @@
*/
package com.android.server.notification;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.concurrent.TimeUnit.HOURS;
import android.test.suitebuilder.annotation.SmallTest;
@@ -42,110 +43,120 @@ public class RateEstimatorTest extends UiServiceTestCase {
@Test
public void testRunningTimeBackwardDoesntExplodeUpdate() throws Exception {
- assertUpdateTime(mTestStartTime);
- assertUpdateTime(mTestStartTime - 1000L);
+ updateAndVerifyRate(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime - 1000L);
}
@Test
public void testRunningTimeBackwardDoesntExplodeGet() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
final float rate = mEstimator.getRate(mTestStartTime - 1000L);
- assertFalse(Float.isInfinite(rate));
- assertFalse(Float.isNaN(rate));
+ assertThat(rate).isFinite();
}
@Test
public void testInstantaneousEventsDontExplodeUpdate() throws Exception {
- assertUpdateTime(mTestStartTime);
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
}
@Test
public void testInstantaneousEventsDontExplodeGet() throws Exception {
- assertUpdateTime(mTestStartTime);
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
final float rate = mEstimator.getRate(mTestStartTime);
- assertFalse(Float.isInfinite(rate));
- assertFalse(Float.isNaN(rate));
+ assertThat(rate).isFinite();
}
@Test
public void testInstantaneousBurstIsEstimatedUnderTwoPercent() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
long nextEventTime = postEvents(eventStart, 0, 5); // five events at \inf
final float rate = mEstimator.getRate(nextEventTime);
- assertLessThan("Rate", rate, 20f);
+ assertThat(rate).isLessThan(20f);
}
@Test
public void testCompactBurstIsEstimatedUnderTwoPercent() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
long nextEventTime = postEvents(eventStart, 1, 5); // five events at 1000Hz
final float rate = mEstimator.getRate(nextEventTime);
- assertLessThan("Rate", rate, 20f);
+ assertThat(rate).isLessThan(20f);
}
@Test
public void testSustained1000HzBurstIsEstimatedOverNinetyPercent() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
long nextEventTime = postEvents(eventStart, 1, 100); // one hundred events at 1000Hz
final float rate = mEstimator.getRate(nextEventTime);
- assertGreaterThan("Rate", rate, 900f);
+ assertThat(rate).isGreaterThan(900f);
}
@Test
public void testSustained100HzBurstIsEstimatedOverNinetyPercent() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
long nextEventTime = postEvents(eventStart, 10, 100); // one hundred events at 100Hz
final float rate = mEstimator.getRate(nextEventTime);
- assertGreaterThan("Rate", rate, 90f);
+ assertThat(rate).isGreaterThan(90f);
}
@Test
public void testRecoverQuicklyAfterSustainedBurst() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
- long nextEventTime = postEvents(eventStart, 10, 1000); // one hundred events at 100Hz
- final float rate = mEstimator.getRate(nextEventTime + 5000L); // two seconds later
- assertLessThan("Rate", rate, 2f);
+ long nextEventTime = postEvents(eventStart, 10, 1000); // one thousand events at 100Hz
+ final float rate = mEstimator.getRate(nextEventTime + 5000L); // five seconds later
+ assertThat(rate).isLessThan(2f);
}
@Test
public void testEstimateShouldNotOvershoot() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
long eventStart = mTestStartTime + 1000; // start event a long time after initialization
- long nextEventTime = postEvents(eventStart, 1, 1000); // one thousand events at 1000Hz
+ long nextEventTime = postEvents(eventStart, 1, 5000); // five thousand events at 1000Hz
final float rate = mEstimator.getRate(nextEventTime);
- assertLessThan("Rate", rate, 1000f);
+ assertThat(rate).isAtMost(1000f);
}
@Test
public void testGetRateWithoutUpdate() throws Exception {
final float rate = mEstimator.getRate(mTestStartTime);
- assertLessThan("Rate", rate, 0.1f);
+ assertThat(rate).isLessThan(0.1f);
}
@Test
public void testGetRateWithOneUpdate() throws Exception {
- assertUpdateTime(mTestStartTime);
+ updateAndVerifyRate(mTestStartTime);
final float rate = mEstimator.getRate(mTestStartTime+1);
- assertLessThan("Rate", rate, 1f);
+ assertThat(rate).isLessThan(1f);
}
- private void assertLessThan(String label, float a, float b) {
- assertTrue(String.format("%s was %f, but should be less than %f", label, a, b), a <= b);
- }
+ @Test
+ public void testEstimateCatchesUpQuickly() {
+ long nextEventTime = postEvents(mTestStartTime, 10, 20); // 20 events at 100Hz
+
+ final float firstBurstRate = mEstimator.getRate(nextEventTime);
+ assertThat(firstBurstRate).isWithin(10f).of(100);
+
+ nextEventTime += HOURS.toMillis(3); // 3 hours later...
+ nextEventTime = postEvents(nextEventTime, 10, 20); // same burst of 20 events at 100Hz
+
+ // Catching up. Rate is not yet 100, since we had a long period of inactivity...
+ float secondBurstRate = mEstimator.getRate(nextEventTime);
+ assertThat(secondBurstRate).isWithin(10f).of(60);
- private void assertGreaterThan(String label, float a, float b) {
- assertTrue(String.format("%s was %f, but should be more than %f", label, a, b), a >= b);
+ // ... but after a few more events, we are there.
+ nextEventTime = postEvents(nextEventTime, 10, 10); // 10 more events at 100Hz
+ secondBurstRate = mEstimator.getRate(nextEventTime);
+ assertThat(secondBurstRate).isWithin(10f).of(100);
}
- /** @returns the next event time. */
+ /** @return the next event time. */
private long postEvents(long start, long dt, int num) {
long time = start;
for (int i = 0; i < num; i++) {
@@ -155,9 +166,8 @@ public class RateEstimatorTest extends UiServiceTestCase {
return time;
}
- private void assertUpdateTime(long time) {
- final float rate = mEstimator.update(time);
- assertFalse(Float.isInfinite(rate));
- assertFalse(Float.isNaN(rate));
+ private void updateAndVerifyRate(long time) {
+ mEstimator.update(time);
+ assertThat(mEstimator.getRate(time)).isFinite();
}
-}
+} \ No newline at end of file
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 2b589bf59682..d179338bf947 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1702,6 +1702,9 @@ public class ActivityStarterTests extends WindowTestsBase {
@Test
public void testRecordActivityMovementBeforeDeliverToTop() {
+ // Mock recents as task is only marked to be in recents
+ mAtm.mTaskSupervisor.setRecentTasks(mock(RecentTasks.class));
+
final Task task = new TaskBuilder(mAtm.mTaskSupervisor).build();
final ActivityRecord activityBot = new ActivityBuilder(mAtm).setTask(task).build();
final ActivityRecord activityTop = new ActivityBuilder(mAtm).setTask(task).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
index b515a9dc0d6b..07d8b8a0c8df 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -27,7 +27,6 @@ import static org.mockito.ArgumentMatchers.any;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.devicestate.DeviceStateManager;
-import android.os.Handler;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -73,20 +72,19 @@ public class DeviceStateControllerTests {
};
mBuilder.setDelegate(mDelegate);
mBuilder.build();
- verify(mMockDeviceStateManager).registerCallback(any(), any());
}
@Test
public void testInitialization() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
}
@Test
public void testInitializationWithNoFoldSupport() {
initialize(false /* supportFold */, false /* supportHalfFolded */);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
// Note that the folded state is ignored.
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState);
}
@@ -94,24 +92,24 @@ public class DeviceStateControllerTests {
@Test
public void testWithFoldSupported() {
initialize(true /* supportFold */, false /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onStateChanged(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
}
@Test
public void testWithHalfFoldSupported() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onStateChanged(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
- mTarget.onStateChanged(mConcurrentDisplayState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState);
assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
}
@@ -121,15 +119,15 @@ public class DeviceStateControllerTests {
assertEquals(1, mTarget.mDeviceStateCallbacks.size());
assertTrue(mTarget.mDeviceStateCallbacks.containsKey(mDelegate));
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
// The callback should not receive state change when the it is unregistered.
mTarget.unregisterDeviceStateCallback(mDelegate);
assertTrue(mTarget.mDeviceStateCallbacks.isEmpty());
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */, mCurrentState);
}
@@ -195,9 +193,7 @@ public class DeviceStateControllerTests {
Resources mockRes = mock(Resources.class);
when(mMockContext.getResources()).thenReturn((mockRes));
mockFold(mSupportFold, mSupportHalfFold);
- Handler mockHandler = mock(Handler.class);
- mTarget = new DeviceStateController(mMockContext, mockHandler,
- new WindowManagerGlobalLock());
+ mTarget = new DeviceStateController(mMockContext, new WindowManagerGlobalLock());
mTarget.registerDeviceStateCallback(mDelegate, MoreExecutors.directExecutor());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 5ec36048234b..dd90e0450280 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -51,14 +51,18 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.DisplayInfo;
import android.view.DisplayShape;
+import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.PrivacyIndicatorBounds;
+import android.view.Surface;
+import android.view.WindowInsets;
import android.view.WindowInsets.Side;
import android.view.WindowManager;
@@ -178,6 +182,44 @@ public class DisplayPolicyTests extends WindowTestsBase {
dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
}
+ @Test
+ public void testChooseNavigationBackgroundWindow() {
+ final WindowState drawBarWin = createOpaqueFullscreen(false);
+ final WindowState nonDrawBarWin = createDimmingDialogWindow(true);
+
+ final WindowState visibleIme = createInputMethodWindow(true, true, false);
+ final WindowState invisibleIme = createInputMethodWindow(false, true, false);
+ final WindowState nonDrawBarIme = createInputMethodWindow(true, false, false);
+
+ assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
+ drawBarWin, null, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ null, null, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ nonDrawBarWin, null, NAV_BAR_BOTTOM));
+
+ assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
+ drawBarWin, visibleIme, NAV_BAR_BOTTOM));
+ assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
+ null, visibleIme, NAV_BAR_BOTTOM));
+ assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow(
+ nonDrawBarWin, visibleIme, NAV_BAR_BOTTOM));
+
+ assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
+ drawBarWin, invisibleIme, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ null, invisibleIme, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ nonDrawBarWin, invisibleIme, NAV_BAR_BOTTOM));
+
+ assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow(
+ drawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ null, nonDrawBarIme, NAV_BAR_BOTTOM));
+ assertNull(DisplayPolicy.chooseNavigationBackgroundWindow(
+ nonDrawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM));
+ }
+
@SetupWindows(addWindows = W_NAVIGATION_BAR)
@Test
public void testUpdateLightNavigationBarLw() {
@@ -350,6 +392,36 @@ public class DisplayPolicyTests extends WindowTestsBase {
&& displayPolicy.updateDecorInsetsInfo());
assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
di.logicalWidth, di.logicalHeight).mConfigInsets.top);
+
+ // Add a window that provides the same insets in current rotation. But it specifies
+ // different insets in other rotations.
+ final WindowState bar2 = createWindow(null, statusBar.mAttrs.type, "bar2");
+ bar2.mAttrs.providedInsets = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(bar2, 0, WindowInsets.Type.statusBars())
+ .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
+ };
+ bar2.mAttrs.setFitInsetsTypes(0);
+ bar2.mAttrs.paramsForRotation = new WindowManager.LayoutParams[4];
+ final int doubleHeightFor90 = STATUS_BAR_HEIGHT * 2;
+ for (int i = ROTATION_0; i <= Surface.ROTATION_270; i++) {
+ final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+ params.setFitInsetsTypes(0);
+ if (i == Surface.ROTATION_90) {
+ params.providedInsets = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(bar2, 0, WindowInsets.Type.statusBars())
+ .setInsetsSize(Insets.of(0, doubleHeightFor90, 0, 0))
+ };
+ } else {
+ params.providedInsets = bar2.mAttrs.providedInsets;
+ }
+ bar2.mAttrs.paramsForRotation[i] = params;
+ }
+ displayPolicy.addWindowLw(bar2, bar2.mAttrs);
+ // Current rotation is 0 and the top insets is still STATUS_BAR_HEIGHT, so no change.
+ assertFalse(displayPolicy.updateDecorInsetsInfo());
+ // The insets in other rotations should be still updated.
+ assertEquals(doubleHeightFor90, displayPolicy.getDecorInsetsInfo(Surface.ROTATION_90,
+ di.logicalHeight, di.logicalWidth).mConfigInsets.top);
}
@SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 866260757df9..114796d17ef1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -25,6 +25,7 @@ import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -38,6 +39,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.spy;
@@ -419,10 +421,10 @@ public class InsetsStateControllerTest extends WindowTestsBase {
@Test
public void testUpdateAboveInsetsState_zOrderChanged() {
- final WindowState ime = createTestWindow("ime");
- final WindowState app = createTestWindow("app");
- final WindowState statusBar = createTestWindow("statusBar");
- final WindowState navBar = createTestWindow("navBar");
+ final WindowState ime = createNonAppWindow("ime");
+ final WindowState app = createNonAppWindow("app");
+ final WindowState statusBar = createNonAppWindow("statusBar");
+ final WindowState navBar = createNonAppWindow("navBar");
final InsetsSourceProvider imeSourceProvider =
getController().getOrCreateSourceProvider(ID_IME, ime());
@@ -430,7 +432,9 @@ public class InsetsStateControllerTest extends WindowTestsBase {
waitUntilHandlersIdle();
clearInvocations(mDisplayContent);
+ imeSourceProvider.updateControlForTarget(app, false /* force */);
imeSourceProvider.setClientVisible(true);
+ verify(mDisplayContent).assignWindowLayers(anyBoolean());
waitUntilHandlersIdle();
// The visibility change should trigger a traversal to notify the change.
verify(mDisplayContent).notifyInsetsChanged(any());
@@ -546,6 +550,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
control2.getInsetsHint().bottom);
}
+ /** Creates a window which is associated with ActivityRecord. */
private WindowState createTestWindow(String name) {
final WindowState win = createWindow(null, TYPE_APPLICATION, name);
win.setHasSurface(true);
@@ -553,6 +558,14 @@ public class InsetsStateControllerTest extends WindowTestsBase {
return win;
}
+ /** Creates a non-activity window. */
+ private WindowState createNonAppWindow(String name) {
+ final WindowState win = createWindow(null, LAST_APPLICATION_WINDOW + 1, name);
+ win.setHasSurface(true);
+ spyOn(win);
+ return win;
+ }
+
private InsetsStateController getController() {
return mDisplayContent.getInsetsStateController();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 7d507e9150e8..34a13bfa855c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -38,6 +38,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCA
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
@@ -461,7 +462,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds() {
final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
WindowInsets.Type.navigationBars());
- taskbar.setInsetsRoundedCornerFrame(true);
+ taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
final Rect opaqueBounds = new Rect(0, 0, 500, 300);
doReturn(opaqueBounds).when(mActivity).getBounds();
@@ -505,7 +506,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testGetCropBoundsIfNeeded_appliesCrop() {
final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
WindowInsets.Type.navigationBars());
- taskbar.setInsetsRoundedCornerFrame(true);
+ taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
// Apply crop if taskbar is expanded
@@ -528,7 +529,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
public void testGetCropBoundsIfNeeded_appliesCropWithSizeCompatScaling() {
final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
WindowInsets.Type.navigationBars());
- taskbar.setInsetsRoundedCornerFrame(true);
+ taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
final float scaling = 2.0f;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 10f4158205e6..b02b774da86a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -49,10 +49,12 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static java.lang.Integer.MAX_VALUE;
@@ -1139,6 +1141,40 @@ public class RecentTasksTest extends WindowTestsBase {
}
@Test
+ public void addTask_taskAlreadyInRecentsMovedToTop_callsTaskNotificationController() {
+ final Task firstTask = createTaskBuilder(".Task").build();
+ final Task secondTask = createTaskBuilder(".Task2").build();
+
+ mRecentTasks.add(firstTask);
+ mRecentTasks.add(secondTask);
+
+ TaskChangeNotificationController controller =
+ mAtm.getTaskChangeNotificationController();
+ clearInvocations(controller);
+
+ // Add firstTask back to top
+ mRecentTasks.add(firstTask);
+ verify(controller).notifyTaskListUpdated();
+ }
+
+ @Test
+ public void addTask_taskAlreadyInRecentsOnTop_doesNotNotify() {
+ final Task firstTask = createTaskBuilder(".Task").build();
+ final Task secondTask = createTaskBuilder(".Task2").build();
+
+ mRecentTasks.add(firstTask);
+ mRecentTasks.add(secondTask);
+
+ TaskChangeNotificationController controller =
+ mAtm.getTaskChangeNotificationController();
+ clearInvocations(controller);
+
+ // Add secondTask to top again
+ mRecentTasks.add(secondTask);
+ verifyZeroInteractions(controller);
+ }
+
+ @Test
public void removeTask_callsTaskNotificationController() {
final Task task = createTaskBuilder(".Task").build();
@@ -1286,7 +1322,7 @@ public class RecentTasksTest extends WindowTestsBase {
doReturn(bufferSize.x).when(buffer).getWidth();
doReturn(bufferSize.y).when(buffer).getHeight();
}
- return new TaskSnapshot(1, new ComponentName("", ""), buffer,
+ return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
Surface.ROTATION_0, taskSize, new Rect() /* contentInsets */,
new Rect() /* letterboxInsets*/, false /* isLowResolution */,
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 2dd34eb5ac4d..d91be16f2538 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -30,6 +30,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
+import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
@@ -3483,7 +3484,7 @@ public class SizeCompatTests extends WindowTestsBase {
final InsetsSource navSource = new InsetsSource(
InsetsSource.createId(null, 0, navigationBars()), navigationBars());
- navSource.setInsetsRoundedCornerFrame(true);
+ navSource.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight));
mActivity.mWmService.mLetterboxConfiguration.setLetterboxActivityCornersRadius(15);
@@ -3531,7 +3532,7 @@ public class SizeCompatTests extends WindowTestsBase {
final InsetsSource navSource = new InsetsSource(
InsetsSource.createId(null, 0, navigationBars()), navigationBars());
- navSource.setInsetsRoundedCornerFrame(true);
+ navSource.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
// Immersive activity has transient navbar
navSource.setVisible(!immersive);
navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight));
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index b69874a97132..84c069691e04 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -218,7 +218,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
Canvas c = buffer.lockCanvas();
c.drawColor(Color.RED);
buffer.unlockCanvasAndPost(c);
- return new TaskSnapshot(MOCK_SNAPSHOT_ID, mTopActivityComponent,
+ return new TaskSnapshot(MOCK_SNAPSHOT_ID, 0 /* captureTime */, mTopActivityComponent,
HardwareBuffer.createFromGraphicBuffer(buffer),
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
mRotation, taskSize, TEST_CONTENT_INSETS, TEST_LETTERBOX_INSETS,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 863523f826b2..ddc729f773b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -485,6 +485,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars())
.setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
};
+ statusBar.mAttrs.setFitInsetsTypes(0);
dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
return statusBar;
}
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
index e57c833e930e..6dcfa6d56ef3 100644
--- a/telecomm/java/android/telecom/ParcelableConference.java
+++ b/telecomm/java/android/telecom/ParcelableConference.java
@@ -21,12 +21,12 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.telecom.IVideoProvider;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import com.android.internal.telecom.IVideoProvider;
-
/**
* A parcelable representation of a conference connection.
* @hide
@@ -287,6 +287,14 @@ public final class ParcelableConference implements Parcelable {
return mCallDirection;
}
+ public String getCallerDisplayName() {
+ return mCallerDisplayName;
+ }
+
+ public int getCallerDisplayNamePresentation() {
+ return mCallerDisplayNamePresentation;
+ }
+
public static final @android.annotation.NonNull Parcelable.Creator<ParcelableConference> CREATOR =
new Parcelable.Creator<ParcelableConference> () {
@Override
diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java
index 2faecc2e3468..5f0c8d729e74 100644
--- a/telecomm/java/android/telecom/StatusHints.java
+++ b/telecomm/java/android/telecom/StatusHints.java
@@ -16,14 +16,19 @@
package android.telecom;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.VisibleForTesting;
import java.util.Objects;
@@ -33,7 +38,7 @@ import java.util.Objects;
public final class StatusHints implements Parcelable {
private final CharSequence mLabel;
- private final Icon mIcon;
+ private Icon mIcon;
private final Bundle mExtras;
/**
@@ -48,11 +53,31 @@ public final class StatusHints implements Parcelable {
public StatusHints(CharSequence label, Icon icon, Bundle extras) {
mLabel = label;
- mIcon = icon;
+ mIcon = validateAccountIconUserBoundary(icon, Binder.getCallingUserHandle());
mExtras = extras;
}
/**
+ * @param icon
+ * @hide
+ */
+ @VisibleForTesting
+ public StatusHints(@Nullable Icon icon) {
+ mLabel = null;
+ mExtras = null;
+ mIcon = icon;
+ }
+
+ /**
+ *
+ * @param icon
+ * @hide
+ */
+ public void setIcon(@Nullable Icon icon) {
+ mIcon = icon;
+ }
+
+ /**
* @return A package used to load the icon.
*
* @hide
@@ -112,6 +137,30 @@ public final class StatusHints implements Parcelable {
return 0;
}
+ /**
+ * Validates the StatusHints image icon to see if it's not in the calling user space.
+ * Invalidates the icon if so, otherwise returns back the original icon.
+ *
+ * @param icon
+ * @return icon (validated)
+ * @hide
+ */
+ public static Icon validateAccountIconUserBoundary(Icon icon, UserHandle callingUserHandle) {
+ // Refer to Icon#getUriString for context. The URI string is invalid for icons of
+ // incompatible types.
+ if (icon != null && (icon.getType() == Icon.TYPE_URI
+ || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
+ String encodedUser = icon.getUri().getEncodedUserInfo();
+ // If there is no encoded user, the URI is calling into the calling user space
+ if (encodedUser != null) {
+ int userId = Integer.parseInt(encodedUser);
+ // Do not try to save the icon if the user id isn't in the calling user space.
+ if (userId != callingUserHandle.getIdentifier()) return null;
+ }
+ }
+ return icon;
+ }
+
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeCharSequence(mLabel);
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 2f96eecb27e3..a996fa100da9 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -83,6 +83,7 @@ java_defaults {
],
data: [
":FlickerTestApp",
+ "trace_config/*",
],
}
@@ -148,8 +149,8 @@ android_test {
name: "FlickerTestsQuickswitch",
defaults: ["FlickerTestsDefault"],
additional_manifests: ["manifests/AndroidManifestQuickswitch.xml"],
- package_name: "com.android.server.wm.flicker.rotation",
- instrumentation_target_package: "com.android.server.wm.flicker.rotation",
+ package_name: "com.android.server.wm.flicker.quickswitch",
+ instrumentation_target_package: "com.android.server.wm.flicker.quickswitch",
srcs: [
":FlickerTestsBase-src",
":FlickerTestsQuickswitch-src",
diff --git a/tests/FlickerTests/AndroidTestTemplate.xml b/tests/FlickerTests/AndroidTestTemplate.xml
index 1176828d47c3..1ede943a9fa2 100644
--- a/tests/FlickerTests/AndroidTestTemplate.xml
+++ b/tests/FlickerTests/AndroidTestTemplate.xml
@@ -3,51 +3,89 @@
* Copyright 2018 Google Inc. All Rights Reserved.
-->
<configuration description="Runs WindowManager {MODULE}">
- <option name="test-tag" value="FlickerTests" />
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<!-- keeps the screen on during tests -->
- <option name="screen-always-on" value="on" />
+ <option name="screen-always-on" value="on"/>
<!-- prevents the phone from restarting -->
- <option name="force-skip-system-props" value="true" />
+ <option name="force-skip-system-props" value="true"/>
<!-- set WM tracing verbose level to all -->
- <option name="run-command" value="cmd window tracing level all" />
+ <option name="run-command" value="cmd window tracing level all"/>
<!-- set WM tracing to frame (avoid incomplete states) -->
- <option name="run-command" value="cmd window tracing frame" />
+ <option name="run-command" value="cmd window tracing frame"/>
<!-- ensure lock screen mode is swipe -->
- <option name="run-command" value="locksettings set-disabled false" />
+ <option name="run-command" value="locksettings set-disabled false"/>
<!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
- <option name="run-command" value="pm disable com.google.android.internal.betterbug" />
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
<!-- restart launcher to activate TAPL -->
- <option name="run-command" value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher" />
- <!-- Ensure output directory is empty at the start -->
- <option name="run-command" value="rm -rf /sdcard/flicker" />
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
<!-- Increase trace size: 20mb for WM and 80mb for SF -->
- <option name="run-command" value="cmd window tracing size 20480" />
- <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920" />
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1" />
- <option name="run-command" value="settings put system show_touches 1" />
- <option name="run-command" value="settings put system pointer_location 1" />
- <option name="teardown-command" value="settings delete secure show_ime_with_hard_keyboard" />
- <option name="teardown-command" value="settings delete system show_touches" />
- <option name="teardown-command" value="settings delete system pointer_location" />
- <option name="teardown-command" value="cmd overlay enable com.android.internal.systemui.navbar.gestural" />
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
<option name="test-file-name" value="{MODULE}.apk"/>
- <option name="test-file-name" value="FlickerTestApp.apk" />
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="{PACKAGE}"/>
- <option name="shell-timeout" value="6600s" />
- <option name="test-timeout" value="6600s" />
- <option name="hidden-api-checks" value="false" />
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6600s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
</test>
+ <!-- Needed for pulling the collected trace config on to the host -->
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
- <option name="directory-keys" value="/sdcard/flicker" />
- <option name="collect-on-run-ended-only" value="true" />
- <option name="clean-up" value="true" />
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.close/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.ime/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.launch/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.quickswitch/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.server.wm.flicker.rotation/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
</metrics_collector>
</configuration>
diff --git a/tests/FlickerTests/manifests/AndroidManifest.xml b/tests/FlickerTests/manifests/AndroidManifest.xml
index 5b00310cd874..de8a3c680768 100644
--- a/tests/FlickerTests/manifests/AndroidManifest.xml
+++ b/tests/FlickerTests/manifests/AndroidManifest.xml
@@ -48,9 +48,4 @@
<uses-library android:name="android.test.runner"/>
<uses-library android:name="androidx.window.extensions" android:required="false"/>
</application>
-
- <!--<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="{{package}}"
- android:label="WindowManager Flicker Tests {MODULE}">
- </instrumentation>-->
</manifest>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 1f120d47a1ac..ed9e14fd86da 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -97,19 +97,19 @@ fun FlickerTest.entireScreenCovered(allStates: Boolean = true) {
if (allStates) {
assertLayers {
this.invoke("entireScreenCovered") { entry ->
- entry.entry.displays.forEach { display ->
+ entry.entry.displays.filter { it.isOn }.forEach { display ->
entry.visibleRegion().coversAtLeast(display.layerStackSpace)
}
}
}
} else {
assertLayersStart {
- this.entry.displays.forEach { display ->
+ this.entry.displays.filter { it.isOn }.forEach { display ->
this.visibleRegion().coversAtLeast(display.layerStackSpace)
}
}
assertLayersEnd {
- this.entry.displays.forEach { display ->
+ this.entry.displays.filter { it.isOn }.forEach { display ->
this.visibleRegion().coversAtLeast(display.layerStackSpace)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING b/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING
deleted file mode 100644
index 945de3363669..000000000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "ironwood-postsubmit": [
- {
- "name": "FlickerTests",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
index 7f496d828996..122a6cbbb98f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.ime
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.common.traces.component.ComponentNameMatcher
@@ -102,6 +103,7 @@ open class CloseImeOnGoHomeTest(flicker: FlickerTest) : BaseTest(flicker) {
@Presubmit
@Test
+ @PlatinumTest(focusArea = "ime")
@IwTest(focusArea = "ime")
override fun cujCompleted() {
super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
index c693ca759bdd..5aa43820e5cb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.ime
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -103,6 +104,7 @@ open class CloseImeToAppOnPressBackTest(flicker: FlickerTest) : BaseTest(flicker
@Presubmit
@Test
+ @PlatinumTest(focusArea = "ime")
@IwTest(focusArea = "ime")
override fun cujCompleted() {
super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
index d5208e060883..6731089f8903 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
@@ -18,6 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -71,6 +72,7 @@ open class CloseImeToHomeOnFinishActivityTest(flicker: FlickerTest) : BaseTest(f
@Presubmit
@Test
+ @PlatinumTest(focusArea = "ime")
@IwTest(focusArea = "ime")
override fun cujCompleted() {
runAndIgnoreAssumptionViolation { entireScreenCovered() }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
index d1335294f629..c70e3cb773d4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.ime
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -52,6 +53,7 @@ open class ShowImeWhenFocusingOnInputFieldTest(flicker: FlickerTest) : BaseTest(
@Presubmit
@Test
+ @PlatinumTest(focusArea = "ime")
@IwTest(focusArea = "ime")
override fun cujCompleted() {
super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
index e6594c969373..a87fae857509 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
@@ -57,7 +57,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ActivitiesTransitionTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ActivityTransitionTest(flicker: FlickerTest) : BaseTest(flicker) {
private val testApp: TwoActivitiesAppHelper = TwoActivitiesAppHelper(instrumentation)
/** {@inheritDoc} */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt
index ac05c7687311..85344a156d7a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt
@@ -27,7 +27,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppAfterCameraTestCfArm(flicker: FlickerTest) : OpenAppAfterCameraTest(flicker) {
+class ActivityTransitionTestCfArm(flicker: FlickerTest) : ActivityTransitionTest(flicker) {
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
index 3a80c6649833..575206591e59 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
@@ -55,7 +55,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppColdFromIcon(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromIconColdTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt
index d33a2724ca44..d453c1ae908a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt
@@ -32,7 +32,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppColdFromIconCfArm(flicker: FlickerTest) : OpenAppColdFromIcon(flicker) {
+class OpenAppFromIconColdTestCfArm(flicker: FlickerTest) : OpenAppFromIconColdTest(flicker) {
@Test
@FlakyTest
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
index 549183f407e2..e74731555642 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
@@ -38,7 +38,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppAfterCameraTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromIntentColdAfterCameraTest(flicker: FlickerTest) :
+ OpenAppFromLauncherTransition(flicker) {
private val cameraApp = CameraAppHelper(instrumentation)
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt
index 43d28fa60e51..177ad7dc09d1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt
@@ -27,8 +27,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromNotificationWarmCfArm(flicker: FlickerTest) :
- OpenAppFromNotificationWarm(flicker) {
+class OpenAppFromIntentColdAfterCameraTestCfArm(flicker: FlickerTest) :
+ OpenAppFromIntentColdAfterCameraTest(flicker) {
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
index 26f88d23cda0..f45f728664cf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
@@ -58,7 +58,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppColdTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromIntentColdTest(flicker: FlickerTest) :
+ OpenAppFromLauncherTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt
index d9a99dadbd3d..0d695f306c00 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt
@@ -31,7 +31,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppColdTestCfArm(flicker: FlickerTest) : OpenAppColdTest(flicker) {
+class OpenAppFromIntentColdTestCfArm(flicker: FlickerTest) : OpenAppFromIntentColdTest(flicker) {
@FlakyTest(bugId = 273696733)
@Test
override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
index 3385830ee77f..a42bff5bf170 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
@@ -58,7 +58,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppWarmTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromIntentWarmTest(flicker: FlickerTest) :
+ OpenAppFromLauncherTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt
index d8b38b30cf13..b6ffcb3df9f3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt
@@ -29,7 +29,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppWarmTestCfArm(flicker: FlickerTest) : OpenAppWarmTest(flicker) {
+class OpenAppFromIntentWarmTestCfArm(flicker: FlickerTest) : OpenAppFromIntentWarmTest(flicker) {
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt
index b21777b30b21..fd4272600d55 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt
@@ -44,8 +44,8 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-open class OpenAppFromLockNotificationCold(flicker: FlickerTest) :
- OpenAppFromNotificationCold(flicker) {
+open class OpenAppFromLockscreenNotificationColdTest(flicker: FlickerTest) :
+ OpenAppFromNotificationColdTest(flicker) {
override val openingNotificationsFromLockScreen = true
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt
index ec92ca65f80a..fd051d50d032 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt
@@ -46,7 +46,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromLockNotificationWarm(flicker: FlickerTest) : OpenAppFromNotificationWarm(flicker) {
+class OpenAppFromLockscreenNotificationWarmTest(flicker: FlickerTest) :
+ OpenAppFromNotificationWarmTest(flicker) {
override val openingNotificationsFromLockScreen = true
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
index 009d61797fe0..37afa8d0caba 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
@@ -37,6 +37,8 @@ import org.junit.runners.Parameterized
* Test cold launching an app from a notification from the lock screen when there is an app overlaid
* on the lock screen.
*
+ * This test assumes the device doesn't have AOD enabled
+ *
* To run this test: `atest FlickerTests:OpenAppFromLockNotificationWithLockOverlayApp`
*/
@RequiresDevice
@@ -44,8 +46,8 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-class OpenAppFromLockNotificationWithLockOverlayApp(flicker: FlickerTest) :
- OpenAppFromLockNotificationCold(flicker) {
+class OpenAppFromLockscreenNotificationWithOverlayAppTest(flicker: FlickerTest) :
+ OpenAppFromLockscreenNotificationColdTest(flicker) {
private val showWhenLockedApp = ShowWhenLockedAppHelper(instrumentation)
// Although we are technically still locked here, the overlay app means we should open the
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt
index eae9ca10c711..30c3ec205bb1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt
@@ -28,7 +28,7 @@ import org.junit.Ignore
import org.junit.Test
/** Base class for app launch tests from lock screen */
-abstract class OpenAppFromLockTransition(flicker: FlickerTest) : OpenAppTransition(flicker) {
+abstract class OpenAppFromLockscreenTransition(flicker: FlickerTest) : OpenAppTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
index 1383ae39f760..924d03f6d302 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
@@ -63,7 +63,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppNonResizeableTest(flicker: FlickerTest) : OpenAppFromLockTransition(flicker) {
+open class OpenAppFromLockscreenViaIntentTest(flicker: FlickerTest) :
+ OpenAppFromLockscreenTransition(flicker) {
override val testApp = NonResizeableAppHelper(instrumentation)
/**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt
index 7bcb91070ecf..d873ec5e83e2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt
@@ -35,8 +35,6 @@ import org.junit.runners.Parameterized
/**
* Test cold launching an app from a notification.
*
- * This test assumes the device doesn't have AOD enabled
- *
* To run this test: `atest FlickerTests:OpenAppFromNotificationCold`
*/
@RequiresDevice
@@ -44,8 +42,8 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-open class OpenAppFromNotificationCold(flicker: FlickerTest) :
- OpenAppFromNotificationWarm(flicker) {
+open class OpenAppFromNotificationColdTest(flicker: FlickerTest) :
+ OpenAppFromNotificationWarmTest(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt
index 8b4a613305c0..fb2a48c2ad7f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt
@@ -29,8 +29,8 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-class OpenAppFromNotificationColdCfArm(flicker: FlickerTest) :
- OpenAppFromNotificationCold(flicker) {
+class OpenAppFromNotificationColdTestCfArm(flicker: FlickerTest) :
+ OpenAppFromNotificationColdTest(flicker) {
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt
index 425e674dec3a..99668ecd0b68 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt
@@ -47,15 +47,13 @@ import org.junit.runners.Parameterized
/**
* Test cold launching an app from a notification.
*
- * This test assumes the device doesn't have AOD enabled
- *
* To run this test: `atest FlickerTests:OpenAppFromNotificationWarm`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromNotificationWarm(flicker: FlickerTest) : OpenAppTransition(flicker) {
+open class OpenAppFromNotificationWarmTest(flicker: FlickerTest) : OpenAppTransition(flicker) {
override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
open val openingNotificationsFromLockScreen = false
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt
index 8b89a8b4c40d..2a2597e1ebe8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt
@@ -27,7 +27,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ActivitiesTransitionTestCfArm(flicker: FlickerTest) : ActivitiesTransitionTest(flicker) {
+class OpenAppFromNotificationWarmTestCfArm(flicker: FlickerTest) :
+ OpenAppFromNotificationWarmTest(flicker) {
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
index ae9ca8007dc8..6ee8ae69924a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
@@ -60,7 +60,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenCameraOnDoubleClickPowerButton(flicker: FlickerTest) :
+class OpenCameraFromHomeOnDoubleClickPowerButtonTest(flicker: FlickerTest) :
OpenAppFromLauncherTransition(flicker) {
private val cameraApp = CameraAppHelper(instrumentation)
override val testApp: StandardAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 855ea3e38b3e..7fbcfec40121 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -129,6 +130,7 @@ open class ChangeAppRotationTest(flicker: FlickerTest) : RotationTransition(flic
}
@Test
+ @PlatinumTest(focusArea = "framework")
@IwTest(focusArea = "framework")
override fun cujCompleted() {
super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 0cbbb83b48ee..44ae14a8e4bb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.ScenarioBuilder
import android.tools.common.traces.component.ComponentNameMatcher
@@ -213,6 +214,7 @@ open class SeamlessAppRotationTest(flicker: FlickerTest) : RotationTransition(fl
}
@Test
+ @PlatinumTest(focusArea = "framework")
@IwTest(focusArea = "framework")
override fun cujCompleted() {
appWindowFullScreen()
diff --git a/tests/FlickerTests/trace_config/trace_config.textproto b/tests/FlickerTests/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..c9a35aca9085
--- /dev/null
+++ b/tests/FlickerTests/trace_config/trace_config.textproto
@@ -0,0 +1,77 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker"
+ atrace_apps: "com.android.server.wm.flicker.other"
+ atrace_apps: "com.android.server.wm.flicker.close"
+ atrace_apps: "com.android.server.wm.flicker.ime"
+ atrace_apps: "com.android.server.wm.flicker.launch"
+ atrace_apps: "com.android.server.wm.flicker.quickswitch"
+ atrace_apps: "com.android.server.wm.flicker.rotation"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/tests/InputMethodStressTest/AndroidManifest.xml b/tests/InputMethodStressTest/AndroidManifest.xml
index 62eee0270cac..e890c9974882 100644
--- a/tests/InputMethodStressTest/AndroidManifest.xml
+++ b/tests/InputMethodStressTest/AndroidManifest.xml
@@ -19,8 +19,7 @@
package="com.android.inputmethod.stresstest">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application>
- <activity android:name=".ImeStressTestUtil$TestActivity"
- android:configChanges="orientation|screenSize"/>
+ <activity android:name=".ImeStressTestUtil$TestActivity"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
index 3d257b29287f..807f0c63668c 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
@@ -199,8 +199,7 @@ public final class AutoShowTest {
Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
TestActivity firstActivity = TestActivity.start(intent1);
// Show Ime with InputMethodManager to ensure the keyboard is on.
- boolean succ = callOnMainSync(firstActivity::showImeWithInputMethodManager);
- assertThat(succ).isTrue();
+ callOnMainSync(firstActivity::showImeWithInputMethodManager);
SystemClock.sleep(1000);
mInstrumentation.waitForIdleSync();
@@ -264,8 +263,7 @@ public final class AutoShowTest {
Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
ImeStressTestUtil.TestActivity secondActivity = activity.startSecondTestActivity(intent2);
// Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
- boolean succ = callOnMainSync(secondActivity::showImeWithInputMethodManager);
- assertThat(succ).isTrue();
+ callOnMainSync(secondActivity::showImeWithInputMethodManager);
SystemClock.sleep(1000);
mInstrumentation.waitForIdleSync();
// Close the second activity
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DefaultImeVisibilityTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DefaultImeVisibilityTest.java
index 299cbf1a84c7..0c267b27490b 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DefaultImeVisibilityTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DefaultImeVisibilityTest.java
@@ -26,8 +26,6 @@ import static com.android.inputmethod.stresstest.ImeStressTestUtil.verifyWindowA
import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsHidden;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
-import static com.google.common.truth.Truth.assertThat;
-
import android.content.Intent;
import android.platform.test.annotations.RootPermissionTest;
import android.platform.test.rule.UnlockScreenRule;
@@ -83,14 +81,11 @@ public final class DefaultImeVisibilityTest {
ImeStressTestUtil.TestActivity activity = ImeStressTestUtil.TestActivity.start(intent);
EditText editText = activity.getEditText();
for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
-
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isTrue();
+ callOnMainSync(activity::showImeWithInputMethodManager);
verifyWindowAndViewFocus(editText, true, true);
waitOnMainUntilImeIsShown(editText);
- boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
- assertThat(hideResult).isTrue();
+ callOnMainSync(activity::hideImeWithInputMethodManager);
waitOnMainUntilImeIsHidden(editText);
}
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 7632ab08b655..5c0212400ff1 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -102,12 +102,10 @@ public final class ImeOpenCloseStressTest {
for (int i = 0; i < iterNum; i++) {
String msgPrefix = "Iteration #" + i + " ";
Log.i(TAG, msgPrefix + "start");
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ callOnMainSync(activity::showImeWithInputMethodManager);
verifyShowBehavior(activity);
- boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
- assertThat(hideResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ callOnMainSync(activity::hideImeWithInputMethodManager);
verifyHideBehavior(activity);
}
@@ -128,14 +126,12 @@ public final class ImeOpenCloseStressTest {
for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
String msgPrefix = "Iteration #" + i + " ";
Log.i(TAG, msgPrefix + "start");
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isTrue();
+ callOnMainSync(activity::showImeWithInputMethodManager);
waitOnMainUntil(
msgPrefix + "IME should be visible",
() -> !activity.isAnimating() && isImeShown(editText));
- boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
- assertThat(hideResult).isTrue();
+ callOnMainSync(activity::hideImeWithInputMethodManager);
waitOnMainUntil(
msgPrefix + "IME should be hidden",
() -> !activity.isAnimating() && !isImeShown(editText));
@@ -156,17 +152,13 @@ public final class ImeOpenCloseStressTest {
List<Integer> intervals = new ArrayList<>();
for (int i = 10; i < 100; i += 10) intervals.add(i);
for (int i = 100; i < 1000; i += 50) intervals.add(i);
- boolean firstHide = false;
for (int intervalMillis : intervals) {
String msgPrefix = "Interval = " + intervalMillis + " ";
Log.i(TAG, msgPrefix + " start");
- boolean hideResult = callOnMainSync(activity::hideImeWithInputMethodManager);
- assertThat(hideResult).isEqualTo(firstHide);
- firstHide = true;
+ callOnMainSync(activity::hideImeWithInputMethodManager);
SystemClock.sleep(intervalMillis);
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isTrue();
+ callOnMainSync(activity::showImeWithInputMethodManager);
verifyShowBehavior(activity);
}
}
@@ -247,8 +239,7 @@ public final class ImeOpenCloseStressTest {
TestActivity activity = TestActivity.start(intent);
// Show InputMethodManager without requesting focus
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isFalse();
+ callOnMainSync(activity::showImeWithInputMethodManager);
int windowFlags = activity.getWindow().getAttributes().flags;
EditText editText = activity.getEditText();
@@ -474,8 +465,7 @@ public final class ImeOpenCloseStressTest {
Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
TestActivity activity = TestActivity.start(intent1);
// Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ callOnMainSync(activity::showImeWithInputMethodManager);
Thread.sleep(1000);
verifyShowBehavior(activity);
@@ -493,6 +483,7 @@ public final class ImeOpenCloseStressTest {
verifyShowBehavior(activity);
}
+ // TODO: Add tests for activities that don't handle the rotation.
@Test
public void testRotateScreenWithKeyboardOn() throws Exception {
Intent intent =
@@ -502,8 +493,7 @@ public final class ImeOpenCloseStressTest {
Collections.singletonList(REQUEST_FOCUS_ON_CREATE));
TestActivity activity = TestActivity.start(intent);
// Show Ime with InputMethodManager to ensure the keyboard is shown on the second activity
- boolean showResult = callOnMainSync(activity::showImeWithInputMethodManager);
- assertThat(showResult).isEqualTo(!(hasUnfocusableWindowFlags(activity)));
+ callOnMainSync(activity::showImeWithInputMethodManager);
Thread.sleep(2000);
verifyShowBehavior(activity);
@@ -514,14 +504,14 @@ public final class ImeOpenCloseStressTest {
Thread.sleep(1000);
Log.i(TAG, "Rotate screen right");
assertThat(uiDevice.isNaturalOrientation()).isFalse();
- verifyShowBehavior(activity);
+ verifyRotateBehavior(activity);
uiDevice.setOrientationLeft();
uiDevice.waitForIdle();
Thread.sleep(1000);
Log.i(TAG, "Rotate screen left");
assertThat(uiDevice.isNaturalOrientation()).isFalse();
- verifyShowBehavior(activity);
+ verifyRotateBehavior(activity);
uiDevice.setOrientationNatural();
uiDevice.waitForIdle();
@@ -569,4 +559,36 @@ public final class ImeOpenCloseStressTest {
waitOnMainUntilImeIsShown(editText);
}
}
+
+ private static void verifyRotateBehavior(TestActivity activity) {
+ // Get the new TestActivity after recreation.
+ TestActivity newActivity = TestActivity.getLastCreatedInstance();
+ assertThat(newActivity).isNotNull();
+ assertThat(newActivity).isNotEqualTo(activity);
+
+ EditText newEditText = newActivity.getEditText();
+ int softInputMode = newActivity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+
+ if (hasUnfocusableWindowFlags(newActivity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(newActivity);
+ return;
+ }
+
+ if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
+ // After rotation, the keyboard would be hidden only when the flag is
+ // SOFT_INPUT_STATE_ALWAYS_HIDDEN. However, SOFT_INPUT_STATE_HIDDEN is different because
+ // it requires appending SOFT_INPUT_IS_FORWARD_NAVIGATION flag, which won't be added
+ // when rotating the devices (rotating doesn't navigate forward to the next app window.)
+ verifyWindowAndViewFocus(newEditText, /*expectWindowFocus*/ true, /*expectViewFocus*/
+ true);
+ waitOnMainUntilImeIsHidden(newEditText);
+
+ } else {
+ // Other cases, keyboard would be shown.
+ verifyWindowAndViewFocus(newEditText, /*expectWindowFocus*/ true, /*expectViewFocus*/
+ true);
+ waitOnMainUntilImeIsShown(newEditText);
+ }
+ }
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
index e16c9152df3e..f3c81942ae42 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
@@ -45,6 +45,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.ThrowingRunnable;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -296,6 +297,8 @@ public final class ImeStressTestUtil {
private static final String TAG = "ImeStressTestUtil.TestActivity";
private EditText mEditText;
private boolean mIsAnimating;
+ private static WeakReference<TestActivity> sLastCreatedInstance =
+ new WeakReference<>(null);
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -336,6 +339,7 @@ public final class ImeStressTestUtil {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
+ sLastCreatedInstance = new WeakReference<>(this);
boolean isUnfocusableView = getIntent().getBooleanExtra(UNFOCUSABLE_VIEW, false);
boolean requestFocus = getIntent().getBooleanExtra(REQUEST_FOCUS_ON_CREATE, false);
int softInputFlags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
@@ -378,6 +382,12 @@ public final class ImeStressTestUtil {
}
}
+ /** Get the last created TestActivity instance. */
+ @Nullable
+ public static TestActivity getLastCreatedInstance() {
+ return sLastCreatedInstance.get();
+ }
+
/** Show IME with InputMethodManager. */
public boolean showImeWithInputMethodManager() {
boolean showResult =
diff --git a/tools/protologtool/Android.bp b/tools/protologtool/Android.bp
index 039bb4e2788c..46745e995f64 100644
--- a/tools/protologtool/Android.bp
+++ b/tools/protologtool/Android.bp
@@ -11,7 +11,7 @@ java_library_host {
name: "protologtool-lib",
srcs: [
"src/com/android/protolog/tool/**/*.kt",
- ":protolog-common-src",
+ ":protolog-common-no-android-src",
],
static_libs: [
"javaparser",
diff --git a/wifi/tests/src/android/net/wifi/nl80211/OWNERS b/wifi/tests/src/android/net/wifi/nl80211/OWNERS
new file mode 100644
index 000000000000..8a75e25cb2f6
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/nl80211/OWNERS
@@ -0,0 +1 @@
+kumachang@google.com